33

让我们假设一段测试代码:

Observable model = Class.forName(fullyQualifiedMethodName).newInstance();
Observer view = Mockito.mock(Observer.class);
model.addObserver(view);
for (Method method : Class.forName(fullyQualifiedMethodName).getDeclaredMethods())
{
  method.invoke(model, composeParams(method));
  model.notifyObservers();
  Mockito.verify(
    view, Mockito.atLeastOnce()
  ).update(Mockito.<Observable>any(), Mockito.<Object>any());
}

Mockito.verify如果模型中的方法没有调用方法,则方法抛出异常Observable.setChanged()

问题:如果不添加loggers/System.print.out,我无法意识到测试失败的当前方法是什么。有没有一种类似于方法的jUnit Assert方法:

Assert.assertEquals(
  String.format("instances %s, %s should be equal", inst1, inst2),
  inst1.getParam(), 
  inst2.getParam()
);

解决方案:

verify(observer, new VerificationMode()
{
  @Override
  public void verify(VerificationData data)
  {
    assertTrue(
        format(
            "method %s doesn't call Observable#setChanged() after changing the state of the model",
            method.toString()
        ),
        data.getAllInvocations().size() > 0);
  }
}).update(Mockito.<Observable>any(), Mockito.<Object>any());
4

7 回答 7

21

这可以解决问题(简单明了):

try {
 verify(myMockedObject, times(1)).doSomthing();
} catch (MockitoAssertionError error) {
    throw new MockitoAssertionError("Was expecting a call to myMockedObject.doSomthing but got ", error);
}
于 2012-07-02T04:12:22.980 回答
18

这个问题很古老,但 Mockito v2.1.0+ 现在有一个内置功能。

verify(mock, description("This will print on failure")).someMethod("some arg");

以下@Lambat评论中包含更多示例:

verify(mock, times(10).description("This will print if the method isn't called 10 times")).someMethod("some arg");
verify(mock, never().description("This will print if someMethod is ever called")).someMethod("some arg");
verify(mock, atLeastOnce().description("This will print if someMethod is never called with any argument")).someMethod(anyString());
于 2019-11-04T02:30:21.727 回答
6

你不能在 mockito 中做。Mockito 语法使得测试预期行为非常容易,但它没有测试状态的概念。

您要做的是在模拟失败时获得一些不在模拟对象中的信息。

如果你真的想这样做,我看到了 2 种通用方法:要么创建自己的验证模式来实现接口

org.mockito.verification;
public static interface VerificationMode

并添加一个类似 atLeastOnceMsd(String msg) 的方法,该方法将在失败的情况下显示消息,或者将模型中的当前测试方法添加到视图对象

例如,在内循环中有一条类似的线。

  view.setName("now we are testing " + method.getName());
于 2010-11-27T12:13:02.820 回答
3

没有允许验证消息的直接 API 调用。但是我认为,如果您更改验证签名以使用方法对象而不是 Mockito.any(),则 Method 类上的 toString() 将启动并为您提供所需的内容。

像这样的东西。

import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.verify;
import static org.mockito.Matchers.eq;

...

Observable model = Class.forName("class name").newInstance();

verify(view, times(1)).update(eq(model), anyObject());

for (Method method : Class.forName("class name").getDeclaredMethods())
{
    method.invoke(model, composeParams(method));
    model.notifyObservers();
    verify(view, atLeastOnce()).update(eq(method), anyObject());
}
于 2010-11-15T16:02:12.640 回答
1

您可以创建匹配器以打印有关当前方法的信息。它会有点笨拙,但它会在验证失败时打印方法名称。

于 2010-11-26T22:06:11.867 回答
1

org.mockito.internal.verification.Description哪些代表提供VerificationMode,但允许覆盖验证消息。

于 2019-09-20T14:18:42.860 回答
1

您可以使用https://www.javadoc.io/doc/org.mockito/mockito-core/2.2.6/org/mockito/verification/VerificationMode.html#description(java.lang.String)
例如。

verify(mocked,times(1).description("This method is expected to invoke once")).someMethod();
于 2021-04-06T16:19:20.803 回答