Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing 如何使用返回void的thenAnswer with方法_Unit Testing_Mockito - Fatal编程技术网

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(..);
}