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
答案 0 :(得分:50)
我只是碰到了我的自我,这给我带来了很多困惑。
正如David上面提到的,Mockito报告了下一个 Mockito方法调用中的错误,这可能不是同一个测试方法。虽然异常消息确实包含对错误发生的实际位置的引用,但我发现错误的测试无法对测试过程产生反作用。而且测试越简单,错误就越有可能出现在下一次测试中!
这是一个简单的解决方案,可确保错误出现在正确的测试方法中:
@After
public void validate() {
validateMockitoUsage();
}
来自Mockito文档here:
如果你滥用它,Mockito会抛出异常,以便你知道你的 测试写得正确。 问题是,Mockito做了 下次使用框架验证(例如,下次验证时, 存根,调用模拟等)。但即使异常可能被抛出 在下一个测试中,异常消息包含一个可导航的堆栈 具有缺陷位置的痕量元素。因此你可以点击和 找到Mockito被滥用的地方。有时候,你可能会 想明确验证框架用法。例如,其中之一 用户希望将validateMockitoUsage()放在他的@After方法中 当他误用Mockito时他立即知道。没有它,他 我会知道它不会比他下次使用它更早 框架。 在@After中使用validateMockitoUsage()的另一个好处 是jUnit运行器将始终在缺陷的测试方法中失败 而普通的下一次'验证可能在下一次测试中失败 方法。但即使JUnit可能会将下一次测试报告为红色,也不要 担心它,只需单击中的可导航堆栈跟踪元素 异常消息,可以立即找到您滥用的地方 的Mockito。
答案 1 :(得分:37)
如果您尝试 {"name":"name"}
Exception in thread"main"com.bluelinelabs.logansquare.NoSuchMapperException:Class me.codeboy.lyd.test.Bean could not be mapped to a JSON object.Perhaps it hasn't been annotated with @JsonObject?
at com.bluelinelabs.logansquare.LoganSquare.mapperFor(LoganSquare.java:165)
at com.bluelinelabs.logansquare.LoganSquare.parse(LoganSquare.java:44)
at me.codeboy.lyd.test.Test1.test(Test1.java:26)
at me.codeboy.lyd.test.Test1.main(Test1.java:13)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by:java.lang.ClassNotFoundException:me.codeboy.lyd.test.Bean$$JsonObjectMapper
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:191)
at com.bluelinelabs.logansquare.LoganSquare.mapperFor(LoganSquare.java:161)
...8more
Process finished with exit code 1
一个需要verify
原始参数的方法,也可能会导致这种情况:
例如,如果我们的方法有这个签名:
any()
你试图像这样验证它,它将失败,上面的消息:
method(long l, String s);
将其更改为verify(service).method(any(), anyString());
,它会起作用:
anyLong()
答案 2 :(得分:3)
由于any()
与boolean
参数一起使用时,我也遇到了同样的错误。显然,它需要为anyBoolean()
。
答案 3 :(得分:2)
在我的情况下,使用 kotlin 是因为未将要测试的功能声明为open
。
该异常注意到不能使用final
/ private / equals / hash方法。
fun increment(){
i++
}
到
open fun increment(){
i++
}
答案 4 :(得分:1)
对我来说,问题结果是测试上下文xml中缺少bean声明。它是由另一个类使用的自定义方面类,其实例是类的构造函数的参数,该参数是验证verify()调用失败的参数。所以我将bean声明添加到上下文xml中,之后它运行良好。
答案 5 :(得分:0)
如果您尝试使用Mockito.verify验证私有方法或程序包私有方法,则会收到此错误。
如果您不想使用PowerMockito,可以将方法设置为保护状态,我建议您添加@VisibleForTesting标记:
之前:
void doSomething() {
//Some behaviour
}
之后:
@VisibleForTesting
protected void doSomething() {
//Some behaviour
}
答案 6 :(得分:0)
这是我的一粒盐!
我发现 Mockito 和 Hibernate Validation 之间存在冲突。
我的解决方案是将我的合同检查(@NotNull、@NotEmpty 等)与模拟测试分开。我还开始使用 validateMockitoUsage()
来确保一切正常运行。
答案 7 :(得分:0)
测试可以单独良好地运行,但是在运行集成测试套件时,它将失败,并显示UnfinishedVerificationException。当我们使用来自模仿者的verify()并具有@EnableRetry时,就会出现问题。 解决方法是使用
public static <T> T unwrapAndVerify(T mock, VerificationMode mode) { return ((T) Mockito.verify(AopTestUtils.getTargetObject(mock), mode)); }
答案 8 :(得分:0)
在以下堆栈上,我也遇到了同样的问题:
4.13
2.28.2
+ Mockito-Inline 2.13.0
4.3.1
我尝试验证lambda调用:
@RunWith(RobolectricTestRunner::class)
class MainViewTest {
@get:Rule
val mockitoRule: MockitoRule = MockitoJUnit.rule()
@Mock private lateinit var mockClickCallback: () -> Unit
@Test
fun `should call clickCallback on the button click`() {
val activity = Robolectric.buildActivity(MainActivity::class.java).create().get()
val viewUnderTest = MainView(activity)
viewUnderTest.setClickCallback(mockClickCallback)
viewUnderTest.button.performClick()
verify(mockClickCallback).invoke() // UnfinishedVerificationException
}
}
然后我在Github上发现了the issue,看来问题出在Robolectric。我使用以下解决方法:
@RunWith(RobolectricTestRunner::class)
class MainViewTest {
private interface UnitFunction: () -> Unit
@Test
fun `should call clickCallback on the button click`() {
val activity = Robolectric.buildActivity(MainActivity::class.java).create().get()
val viewUnderTest = MainView(activity)
val mockClickCallback = mock(UnitFunction::class.java) as () -> Unit
viewUnderTest.setClickCallback(mockClickCallback)
viewUnderTest.button.performClick()
verify(mockClickCallback).invoke() // OK
}
}
答案 9 :(得分:0)
更改为@RunWith(PowerMockRunner.class)
,问题消失了。
之前使用的是@RunWith(MockitoJUnitRunner.class)
。
希望对某人有帮助。
答案 10 :(得分:0)
上面的两个答案建议在每次测试后使用validateMockitoUsage()方法。
尽管这是正确的,但我发现使用@ExtendWith(MockitoExtension.class)
来注释您的班级
在Junit 5中,当添加一些不错的Mockito功能时,效果相同。
对我来说看起来也更干净。
我猜Junit 4 @RunWith(MockitoJUnitRunner.class)
会产生类似的影响,但我没有测试。
答案 11 :(得分:0)
我遇到了相同的错误
org.mockito.exceptions.misusing.UnfinishedVerificationException:
Missing method call for verify(mock) here:
-at com.xxx.MyTest.testRun_Should_xxx_When_yyy(MyTest.java:127)
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.
Mocking methods declared on non-public parent classes is not supported.
at com.xxx.MyTest.validate(MyTest.java:132)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.internal.runners.MethodRoadie.runAfters(MethodRoadie.java:145)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:99)
...
在我的情况下,由于我在调用 Mockito.verify(...)之前使用了 PowerMockito.verifyStatic(),因此产生了错误,将 PowerMockito.verifyStatic()移至最后一行(或将其删除)。
发件人:
PowerMockito.verifyStatic();
Mockito.verify(myMock, Mockito.times(1)).myMockedMethod(anyString(), anyString(), anyString(), any(XXX.class), any(YYY.class), any(ZZZ.class));
收件人:
Mockito.verify(myMock, Mockito.times(1)).myMockedMethod(anyString(), anyString(), anyString(), any(XXX.class), any(YYY.class), any(ZZZ.class));
PowerMockito.verifyStatic();
答案 12 :(得分:0)
使用Junit 5,您可以添加以下内容以在控制台中显示更有意义的Mockito异常
@AfterEach
public void validate() {
validateMockitoUsage()
}
答案 13 :(得分:0)
我有类似的问题,我找到了解决这个问题的方法。您要验证的模拟对象已被重置,因此您应该重置它。您可以在测试用例函数之前重置(模拟),这可能会有所帮助。
答案 14 :(得分:0)
我的类MyRepository
有类似的例外org.mockito.exceptions.misusing.UnfinishedVerificationException: 缺少方法调用验证(模拟): - &GT; at MyRepository $$ FastClassBySpringCGLIB $$ de8d8358.invoke()
正确验证的示例:
verify(mock).doSomething()
当我为MyRepository和mock接口创建接口但未实现时,问题得到了解决。 似乎spring创建了一些CGLIB代理,它导致了UnfinishedVerificationException异常。
答案 15 :(得分:-1)
我不知道你的&#34; classUnderTest&#34;来自,但请确保它嘲笑,不是真正的。 我在下面的测试用例中遇到了同样的问题:
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(...)嘲笑。
答案 16 :(得分:-1)
在使用 mockStatic 方法并多次调用 Mockito.verify 时遇到同样的异常,但传递的是接口而不是实现类。
错误代码:
try (MockedStatic<Service> staticMock = Mockito.mockStatic(Service.class, Mockito.CALLS_REAL_METHODS)) {
staticMock.verify(() -> ServiceImpl.method()); // passed without errors
staticMock.verify(() -> ServiceImpl.method()); // throws UnfinishedVerificationException
}
固定代码:
try (MockedStatic<ServiceImpl> staticMock = Mockito.mockStatic(Service.class, Mockito.CALLS_REAL_METHODS)) {
staticMock.verify(() -> ServiceImpl.method());
staticMock.verify(() -> ServiceImpl.method());
}
这显然是我的错误,但 UnfinishedVerificationException 消息没有帮助