如何在每次调用时不带参数地更改模拟方法的返回值?

Van*_*ard 2 java unit-testing mockito

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

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Tim*_*kle 6

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

@Test
public void testIterate() throws Exception {

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

    iteratorClass.iterate();
}
Run Code Online (Sandbox Code Playgroud)

或作为 VarAgs:

@Test
public void testIterate() throws Exception {

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

    iteratorClass.iterate();
}
Run Code Online (Sandbox Code Playgroud)

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