我有一个计算器界面:
public interface ICalculator {
public double evaluate(String expression);
}
我还有一个View界面:
public interface IView {
public void appendAnswer(double anwer);
}
我的Controller类有一个方法:
public void handle(String inputExpression) {
view.appendAnswer(calculator.evaluate(inputExpression));
}
我正在尝试使用Mockito为句柄创建单元测试。
private Controller controller;
@Mock
ICalculator calculator;
IView view;
@Before
public void setup() {
controller = new Controller();
calculator = mock(ICalculator.class);
view = mock(IView.class);
controller.setCalculator(calculator);
controller.setView(view);
//need a when here?
我需要测试的是当void方法句柄收到一个String时, 使用相应的double参数调用view.appendAnswer。
@Test
public void testControllerHandleMethodCallsViewAppendAnswerMethodPassingADouble() {
controller.handle("2.0");
verify(view, times(1)).appendAnswer(2.0);
}
失败"预期iView.appendAnswer(2.0),实际iView.appendAnswer(0.0)"。 试图找到答案让我相信我在setup()参数中需要一个when子句, 但我一直无法弄清楚语法。
答案 0 :(得分:3)
你嘲笑了你的计算器
calculator = mock(ICalculator.class);
对于大多数参考类型,其所有方法都会返回一些默认值,null
,数字类型为0
,false
为boolean
。
如果您希望这些方法返回预设值,则需要将它们存根。您可以使用Mockito#when(Object)
。
Mockito.when(calculator.someMethod()).thenXyz()
Xyz 取决于您想要做什么。在这种情况下,我假设你想要
calculator.evaluate(inputExpression)
评估方法在给定任何2.0
值时返回String
。
你可以用
做到这一点Mockito.when(calculator.evaluate(Mockito.any(String.class))).thenReturn(2.0);
或者,如果您已经知道将传递哪个String
值,则可以直接使用
String expression = ...;
Mockito.when(calculator.evaluate(expression)).thenReturn(2.0);
在这种情况下,您可以验证是否使用正确的值调用了evaluate
verify(calculator).evaluate(expression);
根据您的评论,您需要Answer
或多或少的
Mockito.when(calculator.evaluate(Mockito.any(String.class))).thenAnswer(new Answer<Double>() {
@Override
public Double answer(InvocationOnMock invocation) throws Throwable {
String argument = invocation.getArgumentAt(0, String.class);
Double returnValue = Double.parseDouble(argument);
return returnValue;
}
});
答案 1 :(得分:2)
首先,你应该在以下时间定义你的模拟行为:
when(calculator.evaluate(anyString()))
.thenReturn(2.0);
然后应该调用要测试的单元:
controller.handle("2.0");
然后验证模拟是否正确:
verify(calculator).evaluate(eq("2.0"));
verify(view).appendAnswer(eq(2.0));
(使用Mockito的许多静态导入,顺便说一句:不使用@Mock注释)