Java Mockito可以在不考虑参数的情况下创建一个方法吗?
我正在尝试使用Mockito测试一些遗留代码 我想将生产中使用的Java Mockito可以在不考虑参数的情况下创建一个方法吗?,java,unit-testing,mocking,mockito,Java,Unit Testing,Mocking,Mockito,我正在尝试使用Mockito测试一些遗留代码 我想将生产中使用的FooDao存根如下: foo = fooDao.getBar(new Bazoo()); 我可以写: when(fooDao.getBar(new Bazoo())).thenReturn(myFoo); 但明显的问题是,getBar()。(诅咒那个新的操作员!) 如果我能以一种不管参数如何都返回myFoo的方式来存根该方法,我会非常喜欢它。如果做不到这一点,我将听取其他解决方案建议,但我真的希望在有合理的测试覆盖率之前避免更
FooDao
存根如下:
foo = fooDao.getBar(new Bazoo());
我可以写:
when(fooDao.getBar(new Bazoo())).thenReturn(myFoo);
但明显的问题是,getBar()。(诅咒那个新的操作员!)
如果我能以一种不管参数如何都返回myFoo
的方式来存根该方法,我会非常喜欢它。如果做不到这一点,我将听取其他解决方案建议,但我真的希望在有合理的测试覆盖率之前避免更改生产代码。
anyObject()
应该适合您的需要
也可以考虑执行<代码> HASCODE()/<代码>和<代码>均衡器()/<代码> > <代码> Bazoo <代码>类。这将使您的代码示例按照您想要的方式工作
when(
fooDao.getBar(
any(Bazoo.class)
)
).thenReturn(myFoo);
或者(为了避免null
s):
别忘了导入匹配器(还有许多其他匹配器):
对于Mockito 2.1.0及更新版本:
import static org.mockito.ArgumentMatchers.*;
对于旧版本:
import static org.mockito.Matchers.*;
这样使用:
when(
fooDao.getBar(
Matchers.<Bazoo>any()
)
).thenReturn(myFoo);
什么时候(
fooDao.getBar(
Matchers.any()
)
).然后返回(myFoo);
在需要导入Mockito.Matchers
之前,另一个选择是依赖良好的老式equals
方法。只要when
mock中的参数等于被测试代码中的参数,那么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 );
}
}
然后,假设您知道someField
的值,您可以这样模拟它
when(fooDao.getBar(new MyPojo(expectedSomeField))).thenReturn(myFoo);
优点:这比任何匹配器都更明确。作为代码的审阅者,我关注初级开发人员编写的代码中的any
,因为它浏览了他们代码的逻辑以生成所传递的适当对象
缺点:有时传递给对象的字段是一个随机ID。在这种情况下,您无法在模拟代码中轻松构造预期的参数对象
另一种可能的方法是使用Mockito的Answer
对象,该对象可与when
方法一起使用Answer
允许截取实际调用,检查输入参数并返回模拟对象。在下面的示例中,我使用any
捕获对被模拟方法的任何请求。但是在答案lambda中,我可以进一步检查Bazo论点。。。也许是为了验证传递给它的ID是否正确。我更喜欢这个而不是任何一个
本身,这样至少可以对参数进行一些检查
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;
} );
总而言之,我喜欢依赖于equals
(预期参数和实际参数应该相等),如果equals不可能(因为无法预测实际参数的状态),我会求助于Answer
来检查参数。同意第二个建议,但出于非技术原因,我仍然选择不这样做。Matchers类已被弃用(请参阅-“该类可能在3.0版中被删除”)@JohannesRabauer我想它应该更改为any()
?我喜欢答案在“接受答案冻结”结束之前。有一个notNull(Bazoo.class)
就像any(Bazoo.class)
(可能在回答这个问题时它还不存在)我有一个稍微特殊的情况,我可以有两个可能的参数之一-Bazoo
或Cazoo
,它们都是,比如说,Azoo
的子类。对于Bazoo
我需要返回foo
,但是对于Cazoo
我需要返回bar
。在这种情况下,建议的Matchers.any()
解决方案不起作用,但是,Matchers.isA()
工作得非常完美。org.mockito.Matchers
现在已被弃用-改用org.mockito.ArgumentMatchers
导入静态org.mockito.ArgumentMatchers.
(请参阅)when(myFoo.knowsWhatsUp()).然后返回(我的钱)代码>这是去润滑!
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;
} );