Java Mockito Spy doReturn调用原始方法
我是莫基托的新手。我知道spy对象永远不会调用Java Mockito Spy doReturn调用原始方法,java,junit,mockito,junit4,Java,Junit,Mockito,Junit4,我是莫基托的新手。我知道spy对象永远不会调用doReturn的原始方法,而是在我的代码中,这是不会发生的 import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Mockito.spy; import org.junit.Before; import org.junit.Test; import org.junit.runner.R
doReturn
的原始方法,而是在我的代码中,这是不会发生的
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.spy;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
class MyClass {
public int method1(){
int x =10;
x = method2(2);
return x;
}
public int method2(int y){
method3();
return 20;
}
public int method3(){
return 30;
}
}
@RunWith(MockitoJUnitRunner.class)
public class Method1Test {
private MyClass myClass = new MyClass();
@Before
public void setup(){}
@Test
public void test01(){
MyClass spyMyClass = spy(myClass);
doReturn(28).when(spyMyClass).method2(any());
int a = spyMyClass.method1();
assertTrue("We did it!!!",a==20);
}
}
下面是错误堆栈跟踪:
java.lang.NullPointerException
在com.Method1Test.test01(Method1Test.java:45)
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
位于sun.reflect.NativeMethodAccessorImpl.invoke(未知源)
在sun.reflect.DelegatingMethodAccessorImpl.invoke处(未知源)
位于java.lang.reflect.Method.invoke(未知源)
位于org.junit.runners.model.FrameworkMethod$1.runReflectVeCall(FrameworkMethod.java:50)
位于org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
位于org.junit.runners.model.FrameworkMethod.invokeeexplosive(FrameworkMethod.java:47)
位于org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
位于org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
位于org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
位于org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
位于org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
位于org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
位于org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
位于org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
访问org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
位于org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
位于org.junit.runners.ParentRunner.run(ParentRunner.java:363)
位于org.mockito.internal.runners.junit45和higherrunnerimpl.run(junit45和higherrunnerimpl.java:37)
位于org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
位于org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
位于org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
位于org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
位于org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
位于org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
位于org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
请有人帮我解决上述问题,并为我提供上述问题的解决方案。该问题是由于传递给
method2
的参数类型不匹配造成的。这就是异常消息的这一部分告诉您的:
org.mockito.exceptions.misusing.invalidUseofMatchers异常:
此处检测到放错位置的参数匹配器:
以下测试通过:
@Test
public void test01(){
MyClass spyMyClass = spy(myClass);
doReturn(28).when(spyMyClass).method2(anyInt());
int a = spyMyClass.method1();
assertTrue("We did it!!!",a==28);
}
这里有两个变化:
anyInt()
而不是any()
a==28
,因为您告诉存根返回28
大家好,欢迎来到Stackoverflow。你能粘贴整个Junit测试类(包括导入)吗?你打算怎么做?我看到你把它打成28,但断言它会返回20。你期望的是什么?@GuillaumeS我已经添加了进口,请检查above@Dean你能告诉我为什么我会在stacktrace上获得NPE吗?为什么上面的doReturn调用上面的spy对象的原始方法?鉴于消息的内容是“我们做到了!!”,他可能希望它失败。我有一个疑问:假设我的方法具有类似于此的公共int method2(Foo-Foo),那么我可以传递为:doReturn(28)。when(spyMyClass)。method2(foomocobj)??如果您阅读完整的异常消息,您将看到Mockito的作者完全预料到了这种情况:“如果最后一个匹配器返回一个类似any()的对象,则此消息可能出现在NullPointerException之后,但存根方法签名需要一个基元参数,在这种情况下,请使用基元替代项。当(mock.get(any());//错误使用,将在(mock.get(anyInt()));//正确使用时引发NPE”因此,您遇到的问题是使用非特定对象匹配器-
any()
-作为基元参数的结果。如果您的参数从基元更改为,例如Foo
,则这将不适用。
@Test
public void test01(){
MyClass spyMyClass = spy(myClass);
doReturn(28).when(spyMyClass).method2(anyInt());
int a = spyMyClass.method1();
assertTrue("We did it!!!",a==28);
}