我想按照方法进行单元测试
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()正在传递该类型的对象,那么它就有点弱了——你想在测试中知道的是,该对象是否是你想要的,并且没有被修改。