的Mockito.验证方法参数

man*_*war 187 java junit unit-testing mockito

我用Google搜索了这个,但没有发现任何相关内容.我有这样的事情:

Object obj = getObject();
Mockeable mock= Mockito.mock(Mockeable.class);
Mockito.when(mock.mymethod(obj )).thenReturn(null);

Testeable testableObj = new Testeable();
testableObj.setMockeable(mock);
command.runtestmethod();
Run Code Online (Sandbox Code Playgroud)

现在,我想验证,mymethod(Object o)内部调用runtestmethod(),是用Object调用的o,而不是其他任何调用.但是我总是通过测试,无论我在验证上做什么,例如:

Mockito.verify(mock.mymethod(Mockito.eq(obj)));
Run Code Online (Sandbox Code Playgroud)

要么

Mockito.verify(mock.mymethod(Mockito.eq(null)));
Run Code Online (Sandbox Code Playgroud)

要么

Mockito.verify(mock.mymethod(Mockito.eq("something_else")));
Run Code Online (Sandbox Code Playgroud)

我总是通过考试.如何完成验证(如果可能)?

谢谢.

eug*_*e82 288

替代ArgumentMatcherArgumentCaptor.

官方例子:

ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);
verify(mock).doSomething(argument.capture());
assertEquals("John", argument.getValue().getName());
Run Code Online (Sandbox Code Playgroud)

也可以使用@Captor注释定义捕获器:

@Captor ArgumentCaptor<Person> captor;
//... MockitoAnnotations.initMocks(this);
@Test public void test() {
    //...
    verify(mock).doSomething(captor.capture());
    assertEquals("John", captor.getValue().getName());
}
Run Code Online (Sandbox Code Playgroud)

  • 重要说明:使用mock调用verify()/ capture()_ after_.我以为它必须在"安装"之前...... (11认同)
  • 哈哈,我没看懂问题,但答案对我帮助很大。谢谢 :-) (4认同)

Mat*_*ley 58

您是否尝试使用对象的.equals方法进行逻辑相等?您可以使用Mockito中包含的argThat匹配器来完成此操作

import static org.mockito.Matchers.argThat
Run Code Online (Sandbox Code Playgroud)

接下来,您可以实现自己的参数匹配器,它将遵循每个对象.equals方法

private class ObjectEqualityArgumentMatcher<T> extends ArgumentMatcher<T> {
    T thisObject;

    public ObjectEqualityArgumentMatcher(T thisObject) {
        this.thisObject = thisObject;
    }

    @Override
    public boolean matches(Object argument) {
        return thisObject.equals(argument);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在使用您的代码,您可以更新它以阅读...

Object obj = getObject();
Mockeable mock= Mockito.mock(Mockeable.class);
Mockito.when(mock.mymethod(obj)).thenReturn(null);

Testeable obj = new Testeable();
obj.setMockeable(mock);
command.runtestmethod();

verify(mock).mymethod(argThat(new ObjectEqualityArgumentMatcher<Object>(obj)));
Run Code Online (Sandbox Code Playgroud)

如果你只是想要EXACT相等(内存中的相同对象),那就去做吧

verify(mock).mymethod(obj);
Run Code Online (Sandbox Code Playgroud)

这将验证它被调用一次.

  • +1为你的答案.但是我想补充说`verify(mock).mymethod(obj);`不检查EXACT相等(内存中的同一个对象).相反,它使用可能已被覆盖的对象equals-method. (2认同)

Boz*_*zho 49

  • 你并不需要eq匹配,如果你不使用其他的匹配.
  • 您没有使用正确的语法 - 您的方法调用应该在...之外.verify(mock).您现在正在启动对方法调用结果的验证,而不验证任何内容(不进行方法调用).因此所有测试都在通过.

您的代码应如下所示:

Mockito.verify(mock).mymethod(obj);
Mockito.verify(mock).mymethod(null);
Mockito.verify(mock).mymethod("something_else");
Run Code Online (Sandbox Code Playgroud)

  • 它通过引用验证 (3认同)

Fre*_*ded 9

我已经以这种方式使用了Mockito.verify

@UnitTest
public class JUnitServiceTest
{
    @Mock
    private MyCustomService myCustomService;


    @Test
    public void testVerifyMethod()
    {
       Mockito.verify(myCustomService, Mockito.never()).mymethod(parameters); // method will never call (an alternative can be pick to use times(0))
       Mockito.verify(myCustomService, Mockito.times(2)).mymethod(parameters); // method will call for 2 times
       Mockito.verify(myCustomService, Mockito.atLeastOnce()).mymethod(parameters); // method will call atleast 1 time
       Mockito.verify(myCustomService, Mockito.atLeast(2)).mymethod(parameters); // method will call atleast 2 times
       Mockito.verify(myCustomService, Mockito.atMost(3)).mymethod(parameters); // method will call at most 3 times
       Mockito.verify(myCustomService, Mockito.only()).mymethod(parameters); //   no other method called except this
    }
}
Run Code Online (Sandbox Code Playgroud)


rit*_*rit 5

您是否检查过可模拟类的 equals 方法?如果这个总是返回 true 或者你针对同一个实例测试同一个实例并且 equal 方法没有被覆盖(因此只检查引用),那么它返回 true。


epo*_*pox 5

这就是您无法通过参数验证的方法:

import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.verify;

    ...
    verify(mock).mymethod(argThat(
                                  (x)->false
                                 ));
Run Code Online (Sandbox Code Playgroud)

在您的特定情况下,最好使用ArgumentMatcher.eq,因此您的失败消息将提供更多信息,例如:Argument(s) are different! Wanted: mock.mymethod(Object_o); Actual invocation has different arguments: mock.mymethod("SOME_OTHER_OBJECT");

import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;

    ...
    Object o = getObject();
    ...
    verify(mock).mymethod(
                        eq(o)
                        );
Run Code Online (Sandbox Code Playgroud)

  • 这是我最喜欢的答案,有效且比其他答案优雅得多。 (2认同)