Java 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的方式来存根该方法,我会非常喜欢它。如果做不到这一点,我将听取其他解决方案建议,但我真的希望在有合理的测试覆盖率之前避免更

我正在尝试使用Mockito测试一些遗留代码

我想将生产中使用的
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;
    } );