我使用的是Mockito 1.9.0。我想在JUnit测试中模拟类的单个方法的行为,所以我有
final MyClass myClassSpy = Mockito.spy(myInstance);
Mockito.when(myClassSpy.method1()).thenReturn(myResults);
问题是,在第二行中,myClassSpy.method1()实际上被调用了,导致了一个异常。我使用模拟的唯一原因是,以后无论何时调用myClassSpy.method1(),都不会调用真正的方法,并且将返回myResults对象。
MyClass是一个接口,myInstance是它的实现。
我需要做什么来纠正这种间谍行为?
我的情况与公认的答案不同。我试图模拟一个包私有方法的实例,该实例不在该包中
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(){}
}
编译是正确的,但是当它试图设置测试时,它反而调用了真正的方法。
将方法声明为protected或public可以修复该问题,但这并不是一个干净的解决方案。
我找到了间谍调用原始方法的另一个原因。
有人想要模拟最后一个类,然后发现了MockMaker:
因为这与我们当前的机制不同,而且有不同的局限性,因为我们想要收集经验和用户反馈,所以这个功能必须被明确激活。可以通过mockito扩展机制创建src/test/resources/mockito-extensions/org.mockito.plugins文件来完成。MockMaker只包含一行:mock-maker-inline
来源:https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2 mock-the-unmockable-opt-in-mocking-of-final-classesmethods
在我合并并将该文件带到我的机器后,测试失败了。
我只需要删除行(或文件),spy()就可以工作了。