莫克托可以在不考虑参数的情况下存根方法



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

我想存根一个在生产中使用的FooDao,如下所示:

foo = fooDao.getBar(new Bazoo());

我可以写:

when(fooDao.getBar(new Bazoo())).thenReturn(myFoo);

但显而易见的问题是,getBar()永远不会使用我为其存根该方法的相同Bazoo对象进行调用。(诅咒那个new操作员!

如果我能以一种无论参数如何都返回myFoo的方式存根该方法,我会很高兴。如果做不到这一点,我会听取其他解决方法建议,但我真的很想避免更改生产代码,直到有合理的测试覆盖率。

when(
  fooDao.getBar(
    any(Bazoo.class)
  )
).thenReturn(myFoo);

或(为避免null):

when(
  fooDao.getBar(
    (Bazoo)notNull()
  )
).thenReturn(myFoo);

不要忘记导入匹配器(许多其他匹配器可用):

对于 Mockito 2.1.0 及更高版本:

import static org.mockito.ArgumentMatchers.*;

对于旧版本:

import static org.mockito.Matchers.*;

http://site.mockito.org/mockito/docs/1.10.19/org/mockito/Matchers.html

anyObject()应该适合您的需求。

此外,您始终可以考虑为 Bazoo 类实现hashCode()equals()。这将使您的代码示例按您想要的方式工作。

像这样使用:

when(
  fooDao.getBar(
    Matchers.<Bazoo>any()
  )
).thenReturn(myFoo);

在需要导入Mockito.Matchers之前

>另一种选择是依靠良好的老式equals方法。 只要when模拟中的参数equals正在测试的代码中的参数,那么 Mockito 就会匹配模拟。

下面是一个示例。

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匹配器更明确。 作为代码审阅者,我密切关注初级开发人员编写的代码中的any,因为它会浏览其代码的逻辑以生成要传递的适当对象。

缺点:有时传递给对象的字段是一个随机 ID。 对于这种情况,您无法在模拟代码中轻松构造预期的参数对象。

另一种可能的方法是使用 Mockito 的 Answer 对象,该对象可与 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;
    } );

所以总而言之,我喜欢依赖equals(其中预期参数和实际参数应该相等),如果不可能相等(由于无法预测实际参数的状态),我将求助于Answer来检查参数。

相关内容

最新更新