6

是否可以更改从模拟对象返回的值?

下面是一个解释我想要做什么的例子。

public class MyClass{
  public void method(Mock obj){
    if(obj.getValue.equals("value"){
      obj.setValue("changedValue");
    }

    anotherObj.call(obj.getValue());
  }

所以上面的类非常简化。如果传入的值等于 value,它将更改返回的值。

@Test
public void test(){
  Mock obj = mock(Mock.class);
  when(obj.getValue()).thenReturn("value");

  testClass.method(obj);

  verify(anotherObj, times(1)).call("changedValue");
}

测试想要验证 anotherObj.call 是否使用更改的值调用,但由于我们已将返回值模拟为 'value',这将失败,因为返回了 'value'。

是否可以使用模拟的 returnValue 创建测试?

4

4 回答 4

3

乔纳坦是对的。如果obj不是复杂对象,则可以避免模拟它并使用真实对象。

如果由于某种原因这是不可能的,mockito 允许定义一系列答案,例如:when(obj.getValue()).thenReturn("value").thenReturn("modifiedValue");这可能是您正在寻找的。

虽然这可能是矫枉过正,只是为了确保一切都好,我也会verify(obj).setValue("changedValue");verify(obj, times(2)).getValue();

于 2013-09-18T09:39:10.580 回答
2

而不是 mocking obj,为什么不使用实际的实现呢?然后大概setValueandgetValue方法会像你期望的那样工作。

尽管我很欣赏这可能是不可能的,但正如您所提到的,您的示例是您实际问题的简化版本。

于 2013-09-18T09:27:11.727 回答
2

这样就够了吗?

    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;
            }
        }
    });

因此,当真正的 getValue 返回某个值时,您可以将其替换为不同的值...

于 2013-09-18T10:41:50.770 回答
0

尝试这个:

@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");
}
于 2014-11-20T12:55:02.163 回答