【问题标题】:How to change return value of mocked method with no argument on each invocation?如何在每次调用时更改没有参数的模拟方法的返回值?
【发布时间】:2017-05-23 12:38:12
【问题描述】:

我希望模拟对象在每个方法调用上返回不同的值。但是该方法没有参数。这是一个例子:

public class MyClass {

    public double getValue() {

        return 0;
    }
}


public class IteratorClass {

    MyClass myClass;

    public IteratorClass(MyClass myClass) {

        this.myClass = myClass;
    }

    public void iterate() {

        for (int i = 0; i < 5; i++) {

            System.out.println("myClass.getValue() = " + myClass.getValue());
        }
    }

}

public class IteratorClassTest {

    private MyClass myClass;
    private IteratorClass iteratorClass;

    @Before
    public void setUp() throws Exception {

        myClass = mock(MyClass.class);
        iteratorClass = spy(new IteratorClass(myClass));

    }

    @Test
    public void testIterate() throws Exception {

        when(myClass.getValue()).thenReturn(10d);
        when(myClass.getValue()).thenReturn(20d);
        when(myClass.getValue()).thenReturn(30d);
        when(myClass.getValue()).thenReturn(40d);
        when(myClass.getValue()).thenReturn(50d);

        iteratorClass.iterate();
    }
}

我在这里监视一个 IteratorClass 并嘲笑 MyClass。我希望 getValue() 方法在每次调用时返回不同的值。但它返回在模拟对象上设置的最后一个值。如果getValue()方法有getValue(int arg)这样的参数,那么可以根据参数返回不同的值。 (例如 getValue(0) -> 返回 10,getValue(1) -> 返回 20 等)。 但是方法没有参数怎么办?

【问题讨论】:

标签: java unit-testing mockito


【解决方案1】:

您可以将连续的返回值指定为链式方法调用(又名 fluent API):

@Test
public void testIterate() throws Exception {

    when(myClass.getValue()).thenReturn(10d)
              .thenReturn(20d)
              .thenReturn(30d)
              .thenReturn(40d)
              .thenReturn(50d);

    iteratorClass.iterate();
}

或作为 VarAgs:

@Test
public void testIterate() throws Exception {

    when(myClass.getValue()).thenReturn(10d,20d,30d,40d,50d);

    iteratorClass.iterate();
}

无论哪种方式,最后一个都将被重新调整以进一步调用该方法。

【讨论】:

  • 带参数的第二个变体似乎更好。
  • @pyramidPeak 大多数情况下,但是如果第 3 次调用应该导致异常,而以下不是呢?
  • 那我觉得这个变种会更合适stackoverflow.com/questions/8088179/…
【解决方案2】:

根据Using Mockito with multiple calls to the same method with the same arguments 的回答,您应该修改您的代码:

...
@Test
public void testIterate() throws Exception {
    when(myClass.getValue()).thenReturn(10d, 20d, 30d, 40d, 50d);
    iteratorClass.iterate();
}
...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 2014-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-09
    相关资源
    最近更新 更多