Eri*_*son 283 java unit-testing mocking mockito
我正在尝试使用Mockito测试一些遗留代码.
我想FooDao
在生产中使用如下的存根:
foo = fooDao.getBar(new Bazoo());
Run Code Online (Sandbox Code Playgroud)
我可以写:
when(fooDao.getBar(new Bazoo())).thenReturn(myFoo);
Run Code Online (Sandbox Code Playgroud)
但显而易见的问题是,getBar()
永远不会使用Bazoo
我为该方法存根的相同对象调用.(诅咒那个new
操作员!)
如果我能以一种myFoo
不管参数而返回的方式存根方法,我都会喜欢它.如果做不到这一点,我会听取其他的解决方法建议,但我真的希望避免更改生产代码,直到有合理的测试覆盖率.
Tom*_*icz 435
when(
fooDao.getBar(
any(Bazoo.class)
)
).thenReturn(myFoo);
Run Code Online (Sandbox Code Playgroud)
或(避免null
s):
when(
fooDao.getBar(
(Bazoo)notNull()
)
).thenReturn(myFoo);
Run Code Online (Sandbox Code Playgroud)
不要忘记导入匹配器(许多其他可用):
对于Mockito 2.1.0和更新版本:
import static org.mockito.ArgumentMatchers.*;
Run Code Online (Sandbox Code Playgroud)
对于旧版本:
import static org.mockito.Matchers.*;
Run Code Online (Sandbox Code Playgroud)
小智 15
使用这样:
when(
fooDao.getBar(
Matchers.<Bazoo>any()
)
).thenReturn(myFoo);
Run Code Online (Sandbox Code Playgroud)
在您需要导入之前 Mockito.Matchers
Buh*_*uhb 13
http://site.mockito.org/mockito/docs/1.10.19/org/mockito/Matchers.html
anyObject应该符合您的需求.
此外,您始终可以考虑为Bazoo类实现hashCode和equals.这将使您的代码示例按您希望的方式工作.
另一种选择是依靠良好的老式equals
方法。只要when
mock中的参数equals
与被测试代码中的参数一致,那么Mockito就会匹配mock。
这是一个例子。
public class MyPojo {
public MyPojo( String someField ) {
this.someField = someField;
}
private String someField;
@Override
public boolean equals( Object o ) {
if ( this == o ) return true;
if ( o == null || getClass() != o.getClass() ) return false;
MyPojo myPojo = ( MyPojo ) o;
return someField.equals( myPojo.someField );
}
}
Run Code Online (Sandbox Code Playgroud)
然后,假设您知道其价值someField
是什么,您可以像这样嘲笑它。
when(fooDao.getBar(new MyPojo(expectedSomeField))).thenReturn(myFoo);
Run Code Online (Sandbox Code Playgroud)
优点:这比any
匹配器更明确。作为代码审阅者,我密切关注any
初级开发人员编写的代码,因为它会浏览他们的代码逻辑以生成传递的适当对象。
缺点:有时传递给对象的字段是随机 ID。对于这种情况,您无法轻松地在模拟代码中构造预期的参数对象。
Answer
另一种可能的方法是使用可与该方法一起使用的Mockito对象when
。 Answer
允许您拦截实际调用并检查输入参数并返回模拟对象。在下面的示例中,我用于any
捕获对被模拟方法的任何请求。但随后在Answer
lambda 中,我可以进一步检查 Bazo 参数...也许可以验证是否向其传递了正确的 ID。我更喜欢这个而any
不是它本身,这样至少可以对论证进行一些检查。
Bar mockBar = //generate mock Bar.
when(fooDao.getBar(any(Bazo.class))
.thenAnswer( ( InvocationOnMock invocationOnMock) -> {
Bazo actualBazo = invocationOnMock.getArgument( 0 );
//inspect the actualBazo here and thrw exception if it does not meet your testing requirements.
return mockBar;
} );
Run Code Online (Sandbox Code Playgroud)
总而言之,我喜欢依赖equals
(预期参数和实际参数应该彼此相等),如果 equals 不可能(由于无法预测实际参数的状态),我将诉诸来Answer
检查参数。