给人的Mockito时UnfinishedVerificationException似乎OK(Moc

2019-08-21 00:09发布

出现的Mockito被抛出UnfinishedVerificationException时,我觉得自己的所做的一切。 这里是我的局部测试案例:

HttpServletRequest req = mock(HttpServletRequest.class);
when(req.getHeader("Authorization")).thenReturn("foo");

HttpServletResponse res = mock(HttpServletResponse.class);

classUnderTest.doMethod(req, res); // Use the mock

verify(res, never());
verify(req).setAttribute(anyString(), anyObject());

而这里的部分类和方法:

class ClassUnderTest extends AnotherClass {
    @Override
    public String doMethod(ServletRequest req, ServletRequest res) {
        // etc.
        return "someString";
    }
}

忽略了一个事实,你不应该不属于您的模拟接口,为什么给人的Mockito我下面的消息?

org.mockito.exceptions.misusing.UnfinishedVerificationException: 
Missing method call for verify(mock) here:
-> at (redacted)

Example of correct verification:
    verify(mock).doSomething()

Also, this error might show up because you verify either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.

at [test method name and class redacted]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
... etc

Answer 1:

我只是碰到这个我自己,它给我带来了很多困惑。

正如David上面提到的Mockito报告中可能不会在同样的测试方法下一个方法的Mockito调用错误。 虽然异常消息确实包含以实际到位的引用发生错误,我觉得有不正确的测试失败适得其反的测试过程。 而测试的简单越有可能一个错误是在接下来的测试中出现!

这里有一个简单的办法,以确保错误出现在正确的测试方法:

@After
public void validate() {
    validateMockitoUsage();
}

从文档的Mockito 这里 :

如果你使用不当,让你知道,如果你的测试是正确写入的Mockito抛出异常。 该小问题,就是做的Mockito使用框架的验证下一个时间 (例如在下一次验证,存根,调用模拟等)。 但是,即使异常可能会在接下来的测试被抛出,异常消息中包含有缺陷的位置可导航堆栈跟踪元素。 因此,你可以点击并找到了的Mockito误用的地方。

虽然有时,你可能想明确地验证框架的使用。 例如,一个用户希望把validateMockitoUsage()在他的@After方法让他知道马上时,他误用的Mockito。 没有它,他会不会比他旁边使用的时间框架越早知道这件事。 在@After有validateMockitoUsage()的一个好处是,JUnit运行总是在测试方法有缺陷失败而普通的“下一次”验证可能会失败,接下来的测试方法。 但是,即使JUnit的下一步可能测试报告为红色,不必担心它,只需点击导航的堆栈跟踪元素异常消息立即找到您的Mockito滥用的地方。



Answer 2:

如果您尝试这也可能会导致verify其预计基本论点的方法any()

例如,如果我们的方法有此签名:

method(long l, String s);

并尝试验证这个样子,这将失败,前述消息:

verify(service).method(any(), anyString());

将其更改为anyLong()它会工作:

verify(service).method(anyLong(), anyString());


Answer 3:

我得到同样的错误,由于使用any()boolean参数,当它显然需要的是anyBoolean()



Answer 4:

对我来说,这个问题竟然是在测试方面的XML缺少bean声明。 这是用于通过另一个类中使用的自定义方面类,它的实例是对类的构造这是参数验证失败()调用的参数。 所以我加入了bean声明上下文XML和它的工作之后的罚款。



Answer 5:

我有类似的异常带班MyRepository

org.mockito.exceptions.misusing.UnfinishedVerificationException:缺少方法调用验证(模拟)的位置: - >在MyRepository $$ FastClassBySpringCGLIB $$ de8d8358.invoke()

正确的验证的实施例:

 verify(mock).doSomething() 

当我创建界面MyRepository,和模拟接口,而不是执行的问题得到了解决。 这似乎春天带来了一些CGLIB代理和它导致UnfinishedVerificationException例外。



Answer 6:

我有一个类似的问题,我发现了一个方法来解决这个问题。 Mock对象,你的验证尚未reseted,所以你应该你的测试用例函数之前重置它。你可以重置(模拟),它可能会有所帮助。



Answer 7:

使用JUnit 5,你可以添加以下在控制台中显示更有意义的异常的Mockito

@AfterEach
public void validate() {
    validateMockitoUsage()
}

也看到这个答案: https://stackoverflow.com/a/22550055/8073652



Answer 8:

如果您尝试验证与Mockito.verify私人或包私有方法,你会得到这个错误。

如果你不希望使用PowerMockito你可以设置你的方法保护,我劝你加入@VisibleForTesting标签:

之前:

void doSomething() {
   //Some behaviour
}

后:

@VisibleForTesting
protected void doSomething() {
   //Some behaviour
}


Answer 9:

我不知道哪里是你的“classUnderTest”从何而来,但是请确保它的嘲笑不是一个真正的一个 。 我有我下面的测试情况下,同样的问题:

MyAgent rpc = new MyAgent("myNodeName");
...
rpc.doSomething();
...
PowerMockito.verifyPrivate(rpc).invoke("initPowerSwitch");
PowerMockito.verifyPrivate(rpc).invoke("init", "192.168.0.23", "b2", 3);

但它消失了下面的测试案例:

MyAgent rpc = PowerMockito.spy(new MyAgent("myNodeName"));
...
rpc.doSomething();
...
PowerMockito.verifyPrivate(rpc).invoke("initPowerSwitch");
PowerMockito.verifyPrivate(rpc).invoke("init", "192.168.0.23", "b2", 3);

注意,对象RPC应PowerMockito.spy(...)被嘲笑。



文章来源: Mockito gives UnfinishedVerificationException when it seems OK