lea*_*hru 16 java unit-testing mocking mockito
我正在使用Mockito来模拟我正在编写测试的同一个类中的方法.我已经在SO上看到了其他答案(同一类中的模拟方法),但可能是我误解了它们,因为我遇到了问题.
class Temp() {
public boolean methodA(String param) {
try {
if(methodB(param))
return true;
return false;
} catch (Exception e) {
e.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的测试方法:
@Test
public void testMethodA() {
Temp temp = new Temp();
Temp spyTemp = Mockito.spy(temp);
Mockito.doReturn(true).when(spyTemp).methodB(Mockito.any());
boolean status = temp.methodA("XYZ");
Assert.assertEquals(true, status);
}
Run Code Online (Sandbox Code Playgroud)
然而,由于方法B的定义被执行,我打印出了预期.我的理解是使用spyTemp来模拟methodB的定义.然而,情况似乎并非如此.
有人可以解释我哪里出错吗?
Kon*_*bun 14
第一个问题是你必须使用spyTest对象来期待Mockito的东西.这与测试不一样.spyTemp是由Mockito对象包裹的temp.
另一个问题是你只是存根methodB(),但试图运行methodA().是的,在你的实现中methodA()调用methodB(),但你调用at this.methodB(),而不是as spyTemp.methodB().在这里你必须明白,只有当你在实例上调用时,mocking才会起作用temp.它由Mockito代理包裹,可以接听你的电话,如果你覆盖了一些方法,它会调用你的新实现而不是原始实现.但是,由于原始方法被称为,在其中你对Mockito代理一无所知.因此,只有在运行时才会调用"覆盖"方法spyTemp.methodB()
这应该工作:
Mockito.doReturn(true).when(spyTemp).methodB(Mockito.any());
boolean status = spyTemp.methodB("XYZ");
Run Code Online (Sandbox Code Playgroud)
您创建了一个间谍并对其进行了嘲笑methodB()。那是正确的!但是您调用methodA()了原始对象。要获得正确的结果,请在间谍中调用它
boolean status = spyTemp.methodA("XYZ");
Run Code Online (Sandbox Code Playgroud)
请注意 Mockito 文档中的以下内容:
Mockito不会将调用委托给传递的真实实例,而是实际创建它的副本。因此,如果您保留真实实例并与之交互,则不要指望被监视的人会知道这些交互及其对真实实例状态的影响。推论是,当在 spy而不是在真实实例上调用unstubbed方法时,您将看不到对真实实例的任何影响。
这是特指你的情况。您保留对的引用temp,然后调用它的methodA. Mockito 根本没有监视那个实例;它在监视spyTemp。所以methodB调用法线。
请注意,您应该完全避免对新代码进行部分模拟。