如何将thenAnswer与返回void的方法一起使用



我想按照方法进行单元测试

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将是检索newObj ie方法参数的合适方法,但不知道如何使用返回void的方法。

更新:
我试过

doAnswer(new Answer<Myclass>() {
              public Myclass answer(InvocationOnMock invocation) {
                  Object[] args = invocation.getArguments();
                  return (Myclass)args[0];
              }
        }).when(dataReqDao.persist(any(Myclass.class)));

编辑:
应该是(谢谢大卫)

 doAnswer(new Answer<Myclass>() {
                  public Myclass answer(InvocationOnMock invocation) {
                      Object[] args = invocation.getArguments();
                      return (Myclass)args[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

您需要使用thenAnswer(或者我个人更喜欢的then),这样您就可以在方法调用时在方法中断言/验证值。

 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);

以下是详细说明:https://akcasoy.wordpress.com/2015/04/09/the-power-of-thenanswer/(用例2)

ArgumentCaptor不会以巧妙的方式进行测试当你像这样改变你的方法时:

public void addRecord(Record record)  
{  
   Myclass newObj = new Mycalss();  
   dataReqDao.persist(newObj);
   // first persist, than set attributes
   newObj.setX(..);
}  

您的Captor测试仍在运行,但应该会失败。由于ArgumentCaptor在调用时不会捕获对象的状态,而只捕获对象ID,因此捕获器在dao调用之前或之后设置属性都无关紧要。然而,一个好的测试应该在每次功能变化时都失败。这是我关于这个案例的文章:

https://akcasoy.wordpress.com/2015/02/03/how-to-ensure-quality-of-junit-tests/(上述使用然后的存根是比使用InOrder方法更好的方法)

Myclass newObj = new Myclass();  

这句话让我很困扰。如果你正在使用依赖注入,你应该让你的工厂给你发送一个该对象的实例。然后,当你创建单元测试时,你可以让测试工厂发送一个MyClass的模拟实例,单元测试也可以访问该实例。然后你可以使用axtavt的captor来查看它是否真的做了它应该做的事情。单元测试的方式没有错,只是,如果你知道any()正在传递该类型的对象,那么它就有点弱了——你想在测试中知道的是,该对象是否是你想要的,并且没有被修改。

相关内容

  • 没有找到相关文章