简体   繁体   English

当从基类中存根方法时,Mockito会抛出NPE

[英]Mockito throws NPE when stubbing method from base class

I use a Hystrix (v. 1.5.6) command in my tested class, and I'm trying to mock it with Mockito (v. 1.10.19). 我在经过测试的课程中使用了Hystrix(v.5.6.1)命令,并且尝试使用Mockito(v.1.10.19)模拟它。

Recently I've had to add a special behavior if the command failed because of a timeout: 最近,如果命令由于超时而失败,我不得不添加特殊行为:

try {
    result = command.execute();
} catch (HystrixRuntimeException err) {
    if (command.isResponseTimedOut()) {
        /** do stuff **/
    }
    /** do stuff **/;
}

This is the code in my test class : 这是我的测试课中的代码:

HttpClientCommand command = mock(HttpClientCommand.class);

when(commandFactory.get(anyString(), anyString(), anyString(), anyMapOf(String.class, String.class))).thenReturn(command);
when(command.execute()).thenThrow(hystrixRuntimeException);
when(command.isResponseTimedOut()).thenReturn(false);

My HttpClientCommand extends the HystrixCommand class. 我的HttpClientCommand扩展了HystrixCommand类。 The execute method is in this class, and I have no problem stubbing it. execute方法在此类中,我对它进行存根没有问题。

The HystrixCommand class then extends the AbstractCommand class, where the isResponseTimedOut method is. 所述HystrixCommand类然后扩展AbstractCommand类,其中isResponseTimedOut方法。 When I try to stub it, I get a NPE from Mockito (on the when(command.isResponseTimedOut()).thenReturn(false); line, before calling any method on my tested class). 当我尝试对它进行存根时,我从Mockito获得了NPE(在对测试类调用任何方法之前,在when(command.isResponseTimedOut()).thenReturn(false);行上)。

Stack trace : 堆栈跟踪 :

java.lang.Exception: Unexpected exception, expected<my.custom.exception> but was<java.lang.NullPointerException>

    at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:28)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    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:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
    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:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: java.lang.NullPointerException
    at com.netflix.hystrix.AbstractCommand.isResponseTimedOut(AbstractCommand.java:1809)
    at com.netflix.hystrix.HystrixCommand.isResponseTimedOut(HystrixCommand.java:46)
    at com.myClassTest.testGetLocation_shouldThrowCustomException_whenRequestException(myClassTest.java:300)
    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:497)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:19)
    ... 22 more

How can I stub this method? 如何存根此方法?

OK the issue is due to a bug with CGLIB, mockito 1.x uses CGLIB. 好的,问题是由于CGLIB的错误所致,mockito 1.x使用CGLIB。 When the method to mock is declared in a non public parent, then CGLIB doesn't intercept the method, hence it executes the real code. 当在非公共父级中声明要模拟的方法时,CGLIB不会拦截该方法,因此它将执行实际代码。 The issue is still available on our old issue tracker : issue 212 该问题在我们的旧问题跟踪器上仍然可用: 问题212

Two options : 两种选择:

  1. Write a public overload in HttpHystrixCommand that will invoke the super method, but since the abstract command have a lot of methods to handle failure, this is probalby not an option that will scale very well. HttpHystrixCommand中编写一个公共重载,该重载将调用super方法,但是由于abstract命令具有许多处理失败的方法,因此probalby并不是一个很好扩展的选项。

  2. Use mockito 2. We have worked with the developer of ByteBuddy – Rafel Winterhalter – to replace CGLIB. 使用嘲笑2。我们已经与ByteBuddy的开发人员Rafel Winterhalter一起替换了CGLIB。 ByteBuddy does not have the same shortcomings of CGLIB which was almost abandonned for years. ByteBuddy没有CGLIB的缺点,而CGLIB的缺点已被放弃了好多年。 Current version is 2.2.29 and at the time of this anwer regular updates are released. 当前版本是2.2.29,并且在此之时会定期发布更新。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 存根方法不起作用:使用Mockito时,尝试使用JDBC语句处理资源而NPE失败 - Stubbing method doesn't work: JDBC statement in try with resources failing with NPE when using Mockito Mockito - 存根方法时出现 NullpointerException - Mockito - NullpointerException when stubbing Method Mockito 存根方法的单元测试抛出 NullPointerException - Mockito Unit Tests stubbing a method throws NullPointerException Mockito在存根时从超类调用真实方法 - Mockito calls real method from superclass when stubbing Mockito 在使用 when 时抛出 NPE - Mockito throws NPE when using when Power Mockito 在方法为私有时引发“未完成的存根”错误,但在方法受保护时不会引发错误 - Power Mockito Throws "Unfinished stubbing" error when method is private, but not error when method is protected 使用Mockito将Class <T>作为参数的方法存根 - Stubbing a method that takes Class<T> as parameter with Mockito 使用Mockito存根测试方法调用时发生NullPointerException - NullPointerException when stubbing a test method call with Mockito 我在使用 Junit5 和 Mockito 存根方法时得到 NPE - I am getting NPE while stubbing the method using Junit5 and Mockito Mockito-尝试匹配原始时,Custom Matcher会抛出NPE - Mockito - Custom Matcher throws NPE when trying to match primitive
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM