我在谷歌上搜索了一下,但没有找到任何相关信息。我得到了这样的东西:

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();

现在,我想验证在runtestmethod()内部调用的mymethod(Object o)是否与对象o一起调用,而不是任何其他方法。但我总能通过测试,不管我用什么来验证,比如:

Mockito.verify(mock.mymethod(Mockito.eq(obj)));

or

Mockito.verify(mock.mymethod(Mockito.eq(null)));

or

Mockito.verify(mock.mymethod(Mockito.eq("something_else")));

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

谢谢你!


当前回答

我用过Mockito。以这种方式验证

@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
    }
}

其他回答

我用过Mockito。以这种方式验证

@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
    }
}

ArgumentMatcher的替代方案是ArgumentCaptor。

官方的例子:

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

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

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

你是否尝试过使用相同的()匹配器?如:

verify(mockObj).someMethod(same(specificInstance));

我也有同样的问题。我尝试了eq()匹配器以及refEq()匹配器,但我总是有误报。当我使用相同的()匹配器时,当参数是不同的实例时测试失败,当参数是相同的实例时测试通过。

你正在尝试使用对象的.equals方法来做逻辑相等吗?你可以利用Mockito中包含的argThat匹配器来做到这一点

import static org.mockito.Matchers.argThat

接下来,你可以实现自己的参数匹配器,它将遵循每个对象的.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);
    }
}

现在使用您的代码,您可以将其更新为…

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)));

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

verify(mock).mymethod(obj);

这将验证它被调用过一次。

你检查过mockable类的equals方法了吗?如果这个方法总是返回true,或者你对同一个实例测试同一个实例,而equal方法没有被覆盖(因此只检查引用),那么它返回true。