我是Mockito的新手,请帮助理解基本知识。
根据我上面的代码,当mocked.add(6,7)
被调用时,应该打印5,但add()
方法没有被调用,代码打印0 ..为什么?该代码的任何解决方案?
import org.mockito.Mockito;
import static org.mockito.Mockito.*;
class Calc{
int add(int a,int b){
System.out.println("add method called");
return a+b;
}
}
class MockTest{
public static void main(String[] args) {
Calc mocked=mock(Calc.class);
when(mocked.add(2,3)).thenReturn(5);
System.out.println(mocked.add(6,7));
}
}
答案 0 :(得分:1)
为了得到5的结果,你必须传递确切的参数,就像设置when..then时一样。否则mockito将返回默认值' value(整数为0:
默认情况下模拟会返回什么值?
为了保持透明和不引人注目的所有Mockito嘲笑 默认回报'不错'值。例如:零,假,空 集合或空值。请参阅有关存根的javadocs以确切了解 默认返回什么值。
如果您想为任何整数返回5,请使用:
when(mocked.add(Mockito.any(Integer.class),Mockito.any(Integer.class))).thenReturn(5);
答案 1 :(得分:0)
“模拟”只是一个模拟“真实”对象行为的空虚拟对象。如果你定义了像when(mocked.add(2,3)).thenReturn(5);
这样的行为,那么你明确告诉这个模拟做什么,当它收到那些确切的值时。
mocked.add(6,7)
此时将返回0
,因为您尚未为这些值定义其行为,因此使用默认值。因此,如果您想要涵盖所有可能的输入,您可以使用@MaciejKowalski发布的解决方案,并使用像Mockito.any(Integer.class)
这样的通用匹配器。
我仍然相信目前还不清楚如何正确处理嘲笑。模拟是一种为被测系统提供外部依赖关系的方法,无需设置整个依赖关系树。通常不会调用该类中的实际方法。这就像when(mocked.add(2,3)).thenReturn(5);
之类的意思。它告诉模拟表现就像真正的依赖,而不是真正掌握它。
示例可能如下所示:
public class TestClass {
private ExternalDependency dep;
public void setDep(ExternalDependency dep) {
this.dep = dep;
}
public int calculate() {
return 5 + dep.doStuff();
}
}
public class ExternalDependency {
public int doStuff() {
return 3;
}
}
现在,在您的测试代码中,您可以使用这样的模拟:
@Test
public void should_use_external_dependency() {
// Aquire a mocked object of the class
ExternalDependency mockedDep = Mockito.mock(ExternalDependency.class);
// Define its behaviour
Mockito.when(mockedDep.doStuff()).thenReturn(20);
TestClass sut = new TestClass();
sut.setDep(mockedDep);
// should return 25, since we've defined the mocks behaviour to return 20
Assert.assertEquals(25, sut.calculate());
}
如果调用sut.calculate()
,则不应该真正调用ExternalDependency
中的方法,而是委托给模拟的存根对象。但是,如果您想调用真实类的真实方法,您可以使用 Spy 代替Mockito.spy(ExternalDependency.class)
,或者您可以使用when(mockedDep.doStuff()).thenCallRealMethod();