Unit testing 如何使用返回void的thenAnswer with方法
我想对以下方法进行单元测试Unit testing 如何使用返回void的thenAnswer with方法,unit-testing,mockito,Unit Testing,Mockito,我想对以下方法进行单元测试 public void addRecord(Record record) { Myclass newObj = new Mycalss(); // It creates newObj object, set some values using record object. // and it adds the newObj in daatbase. dataReqDao.persist(newObj); } 我已经模拟
public void addRecord(Record record)
{
Myclass newObj = new Mycalss();
// It creates newObj object, set some values using record object.
// and it adds the newObj in daatbase.
dataReqDao.persist(newObj);
}
我已经模拟了dataReqDao.persist
方法,但如何验证是否将正确的值复制到了newObj对象中?我想得到newObj对象
我认为thenAnswer
将是检索新对象ie方法参数的合适方法,但不知道如何使用返回void的it方法
更新:我试过了
doAnswer(新答案(){
公共Myclass应答(调用锁调用){
对象[]args=invocation.getArguments();
返回(Myclass)参数[0];
}
}).when(dataReqDao.persist(any(Myclass.class));
编辑:应该是(谢谢大卫)
doAnswer(新答案(){
公共Myclass应答(调用锁调用){
对象[]args=invocation.getArguments();
返回(Myclass)参数[0];
}
}).when(dataReqDao).persist(any(Myclass.class));
您可以创建一个自定义项来检查该对象的字段,或者使用来捕获该对象以供进一步检查
例如:
ArgumentCaptor<Myclass> c = ArgumentCaptor.forClass(Myclass.class);
verify(dateReqDao).persist(c.capture());
Myclass newObj = c.getValue();
... // Validate newObj
ArgumentCaptor c=ArgumentCaptor.forClass(Myclass.class);
验证(dateReqDao).persist(c.capture());
Myclass newObj=c.getValue();
... // 验证newObj
那句话使我烦恼。如果您使用的是依赖项注入,那么应该让工厂向您发送该对象的实例。然后,当您创建单元测试时,您可以让测试工厂发送一个MyClass的模拟实例,单元测试也可以访问该实例。然后你可以使用axtavt的captor来查看它是否真的做了它应该做的事情。单元测试的方式没有什么问题,只是如果您知道它正在传递一个该类型的对象,那么any()就有点弱——在测试中,您想知道的是该对象是否是您想要的并且没有被修改 您需要使用然后回答(或者我个人更喜欢的然后),这样您就可以在方法调用时在方法中断言/验证值
when(dataReqDao.persist(newObj)).then(new Answer<Void>() {
@Override
public Void answer(final InvocationOnMock invocation) {
Myclass newObjActual = (Myclass) invocation.getArguments()[0];
// Control
assertEquals(..., newObjActual.getX());
assertEquals(..., newObjActual.getY());
return null;
}
});
// Run Test
x.addRecord(record);
。。您的Captor测试仍在运行,但应该失败。因为ArgumentCaptor在调用时不捕获对象的状态,而只捕获objectId,所以您在dao调用之前还是之后设置属性对captor来说都无关紧要。然而,一个好的测试应该在每次功能改变时失败。以下是我的文章,正是关于这个案例的:
(上面用然后的stubing是一种比按顺序方法更好的方法)在您的更新中,括号位于错误的位置。我不确定这是否是你的错误的原因,因为它的其余部分看起来还行。所以它应该是
doAnswer(…).when(dataReqDao).persist(…)代码>有用吗?@David:谢谢David。实际上,我已经纠正了这一点,但是忘记了更新我的问题。这并没有执行一个聪明的测试,因为ArgumentCaptor在调用时不捕获对象的状态,而只捕获objectId。因此,即使在dao调用之后在方法中使用setter,测试也是绿色的。但是一个好的测试应该在每次功能改变时失败。我写了我的建议作为对这篇文章的回答。
ArgumentCaptor<Myclass> c = ArgumentCaptor.forClass(Myclass.class);
verify(dateReqDao).persist(c.capture());
Myclass newObj = c.getValue();
... // Validate newObj
Myclass newObj = new Myclass();
when(dataReqDao.persist(newObj)).then(new Answer<Void>() {
@Override
public Void answer(final InvocationOnMock invocation) {
Myclass newObjActual = (Myclass) invocation.getArguments()[0];
// Control
assertEquals(..., newObjActual.getX());
assertEquals(..., newObjActual.getY());
return null;
}
});
// Run Test
x.addRecord(record);
public void addRecord(Record record)
{
Myclass newObj = new Mycalss();
dataReqDao.persist(newObj);
// first persist, than set attributes
newObj.setX(..);
}