Java Mockito 允许设置模拟返回值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18868338/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mockito allow mocked return value to be set
提问by well_i
Is it possible to change the value that is returned from a mocked object?
是否可以更改从模拟对象返回的值?
Below is an example that explains what I am trying to do.
下面是一个示例,解释了我正在尝试做的事情。
public class MyClass{
public void method(Mock obj){
if(obj.getValue.equals("value"){
obj.setValue("changedValue");
}
anotherObj.call(obj.getValue());
}
So the above class is very simplified. It will change the value returned if the value passed in equals value.
所以上面的类非常简化。如果传入的值等于 value,它将更改返回的值。
@Test
public void test(){
Mock obj = mock(Mock.class);
when(obj.getValue()).thenReturn("value");
testClass.method(obj);
verify(anotherObj, times(1)).call("changedValue");
}
The test want to verify that the anotherObj.call is called with the changed value, but since we have mocked the return value to be 'value' this will fail as 'value' is returned.
该测试想要验证是否使用更改后的值调用 anotherObj.call,但由于我们将返回值模拟为 'value',这将在返回 'value' 时失败。
Is it possible to create a test using a mocked returnValue?
是否可以使用模拟的 returnValue 创建测试?
采纳答案by Morfic
Johnatan is right. If obj
is not a complex object, you can avoid mocking it and use a real one.
乔纳坦是对的。如果obj
不是一个复杂的对象,您可以避免模拟它并使用真实的对象。
If for some reason this is not possible, mockito allows to define a series of answers, eg: when(obj.getValue()).thenReturn("value").thenReturn("modifiedValue");
which could be what you are looking for.
如果由于某种原因这是不可能的,mockito 允许定义一系列答案,例如:when(obj.getValue()).thenReturn("value").thenReturn("modifiedValue");
这可能是您正在寻找的。
Although it might be overkill, just to make sure that all was ok, I would also verify(obj).setValue("changedValue");
and verify(obj, times(2)).getValue();
虽然这可能有点矫枉过正,只是为了确保一切正常,我也会verify(obj).setValue("changedValue");
和verify(obj, times(2)).getValue();
回答by Jonathan
Instead of mocking obj
, why not use the actual implementation? Then presumably the setValue
and getValue
methods would work as you would expect.
而不是嘲笑obj
,为什么不使用实际实现?那么大概setValue
和getValue
方法会按您的预期工作。
Although I appreciate this might not be possible, as you have mentioned your example is a much simplified version of your actual problem.
虽然我很欣赏这可能是不可能的,但正如您所提到的,您的示例是您实际问题的简化版本。
回答by Michael Wiles
Would this suffice?
这样就够了吗?
ObjectUnderTest objectUnderTest = new ObjectUnderTest();
ObjectUnderTest spy2 = Mockito.spy(objectUnderTest);
when(spy2.getValue()).thenAnswer(new Answer<String>() {
@Override
public String answer(InvocationOnMock invocation) throws Throwable {
Object realAnswer = invocation.callRealMethod();
if (realAnswer.equals("SOME VALUE")) {
return "SOME OTHER VALUE";
}else {
return realAnswer;
}
}
});
So when the real getValue returns some value you can replace that with a different value...
因此,当真正的 getValue 返回某个值时,您可以将其替换为不同的值...
回答by Michael Kretinin
Try this:
尝试这个:
@Test
public void test(){
Mock obj = mock(Mock.class);
doCallRealMethod().when(obj).setValue(any(String.class));
when(obj.getValue()).thenCallRealMethod();
obj.setValue("value");
testClass.method(obj);
verify(anotherObj, times(1)).call("changedValue");
}