Java Mockito:试图监视方法正在调用原始方法
我正在使用Mockito 1.9.0。我希望在JUnit测试中模拟类的单个方法的行为,因此Java Mockito:试图监视方法正在调用原始方法,java,junit,mockito,Java,Junit,Mockito,我正在使用Mockito 1.9.0。我希望在JUnit测试中模拟类的单个方法的行为,因此 final MyClass myClassSpy = Mockito.spy(myInstance); Mockito.when(myClassSpy.method1()).thenReturn(myResults); 问题是,在第二行中,myClassSpy.method1()实际上被调用,导致异常。我使用mock的唯一原因是,以后无论何时调用myClassSpy.method1(),都不会调用真正的
final MyClass myClassSpy = Mockito.spy(myInstance);
Mockito.when(myClassSpy.method1()).thenReturn(myResults);
问题是,在第二行中,myClassSpy.method1()
实际上被调用,导致异常。我使用mock的唯一原因是,以后无论何时调用myClassSpy.method1()
,都不会调用真正的方法,并且会返回myResults
对象
MyClass
是一个接口,myInstance
是该接口的一个实现,如果这很重要的话
我需要做些什么来纠正这种间谍行为?让我引用一下:
重要的是,我已经掌握了监视真实物体的方法!
有时,当(对象)用于刺杀间谍时,是不可能的。例如:
List list = new LinkedList();
List spy = spy(list);
// Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)
when(spy.get(0)).thenReturn("foo");
// You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
在您的情况下,它是这样的:
doReturn(resultsIWant).when(myClassSpy).method1();
让我引述:
重要的是,我已经掌握了监视真实物体的方法!
有时,当(对象)用于刺杀间谍时,是不可能的。例如:
List list = new LinkedList();
List spy = spy(list);
// Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)
when(spy.get(0)).thenReturn("foo");
// You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
在您的情况下,它是这样的:
doReturn(resultsIWant).when(myClassSpy).method1();
我的情况与公认的答案不同。我试图为一个不在包中的实例模拟包私有方法
package common;
public class Animal {
void packageProtected();
}
package instances;
class Dog extends Animal { }
还有考试班
package common;
public abstract class AnimalTest<T extends Animal> {
@Before
setup(){
doNothing().when(getInstance()).packageProtected();
}
abstract T getInstance();
}
package instances;
class DogTest extends AnimalTest<Dog> {
Dog getInstance(){
return spy(new Dog());
}
@Test
public void myTest(){}
}
包通用;
公共抽象类动物测试{
@以前
设置(){
doNothing().when(getInstance()).packageProtected();
}
抽象T getInstance();
}
包实例;
类DogTest扩展了AnimalTest{
Dog getInstance(){
返回间谍(新狗());
}
@试验
public void myTest(){}
}
编译是正确的,但是当它试图设置测试时,它会调用real方法
声明该方法受保护或公开可以修复问题,尽管它不是一个干净的解决方案。我的案例与公认的答案不同。我试图为一个不在包中的实例模拟包私有方法
package common;
public class Animal {
void packageProtected();
}
package instances;
class Dog extends Animal { }
还有考试班
package common;
public abstract class AnimalTest<T extends Animal> {
@Before
setup(){
doNothing().when(getInstance()).packageProtected();
}
abstract T getInstance();
}
package instances;
class DogTest extends AnimalTest<Dog> {
Dog getInstance(){
return spy(new Dog());
}
@Test
public void myTest(){}
}
包通用;
公共抽象类动物测试{
@以前
设置(){
doNothing().when(getInstance()).packageProtected();
}
抽象T getInstance();
}
包实例;
类DogTest扩展了AnimalTest{
Dog getInstance(){
返回间谍(新狗());
}
@试验
public void myTest(){}
}
编译是正确的,但是当它试图设置测试时,它会调用real方法
宣布该方法受保护或公开解决了这个问题,尽管这不是一个干净的解决方案。托马兹·努尔基维茨的回答似乎并没有说明全部情况强> NB Mockito版本:1.10.19 我是一个莫基托新手,所以无法解释以下行为:如果有专家可以改进这个答案,请放心 这里讨论的方法,
getContentStringValue
,是非最终
和非静态
此行调用原始方法getContentStringValue
:
doReturn( "dummy" ).when( im ).getContentStringValue( anyInt(), isA( ScoreDoc.class ));
doReturn( "dummy" ).when( im ).getContentStringValue( anyInt(), any( ScoreDoc.class ));
此行不调用原始方法getContentStringValue
:
doReturn( "dummy" ).when( im ).getContentStringValue( anyInt(), isA( ScoreDoc.class ));
doReturn( "dummy" ).when( im ).getContentStringValue( anyInt(), any( ScoreDoc.class ));
出于我无法回答的原因,使用isA()
会导致doReturn
的预期(?“不要调用方法”行为失败
让我们看看这里涉及的方法签名:它们都是匹配器的静态方法。Javadoc说这两个函数都返回null
,这本身就有点难理解。假定检查作为参数传递的类
对象,但结果从未计算或丢弃。鉴于null
可以代表任何类,并且您希望模拟方法不会被调用,那么isA(…)
和any(…)
的签名不能只返回null
而不是泛型参数*
无论如何:
public static <T> T isA(java.lang.Class<T> clazz)
public static <T> T any(java.lang.Class<T> clazz)
publicstatictisa(java.lang.Class clazz)
公共静态T any(java.lang.Class clazz)
API文档没有给出任何关于这方面的线索。它似乎还说,这种“不调用方法”行为的必要性“非常罕见”。就我个人而言,我一直都在使用这种技巧:我发现模仿通常包括几句“设置场景”的台词。。。然后调用一个方法,该方法将“播放”已上演的模拟上下文中的场景。。。当你在设置布景和道具的时候,你最不想看到的就是演员们从左边进入舞台,开始表演他们的心
但这远远超出了我的工资等级。。。我请任何路过的莫基托大祭司解释
*“通用参数”是正确的术语吗?托马兹·努尔基维茨的答案似乎并没有说明全部情况强>
NB Mockito版本:1.10.19
我是一个莫基托新手,所以无法解释以下行为:如果有专家可以改进这个答案,请放心
这里讨论的方法,getContentStringValue
,是非最终
和非静态
此行调用原始方法getContentStringValue
:
doReturn( "dummy" ).when( im ).getContentStringValue( anyInt(), isA( ScoreDoc.class ));
doReturn( "dummy" ).when( im ).getContentStringValue( anyInt(), any( ScoreDoc.class ));
此行不调用原始方法getContentStringValue
:
doReturn( "dummy" ).when( im ).getContentStringValue( anyInt(), isA( ScoreDoc.class ));
doReturn( "dummy" ).when( im ).getContentStringValue( anyInt(), any( ScoreDoc.class ));
出于我无法回答的原因,使用isA()
会导致doReturn
的预期(?“不要调用方法”行为失败
让我们看看这里涉及的方法签名:它们都是匹配器的静态方法。Javadoc说这两个函数都返回null
,这本身就有点难理解。假定检查作为参数传递的类
对象,但结果从未计算或丢弃。假设null
可以代表任何类,并且您是
doReturn(0).when(spy , "handleAction", any(List.class), anyString());