Vanguard
Vanguard

Reputation: 1396

How to change return value of mocked method with no argument on each invocation?

I want mocked object return different values on each its method call. But the method has no parameter. Here is an example:

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

I'm spying here an IteratorClass and mocking MyClass. I want getValue() method return different value on each call. But it is returning last value set on mocked object. If getValue() method has some parameter like getValue(int arg), then could return different value according to the parameter. (e.g. getValue(0) -> return 10, getValue(1) -> return 20 etc). But how to be when method has no parameters?

Upvotes: 4

Views: 7590

Answers (2)

Dmitry Gorkovets
Dmitry Gorkovets

Reputation: 2276

According to answer from Using Mockito with multiple calls to the same method with the same arguments you should modify your code:

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

Upvotes: 2

Timothy Truckle
Timothy Truckle

Reputation: 15622

You can either specify the consecutive return values as chained method calls (aka fluent API):

@Test
public void testIterate() throws Exception {

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

    iteratorClass.iterate();
}

or as VarAgs:

@Test
public void testIterate() throws Exception {

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

    iteratorClass.iterate();
}

either way that last one will be retuned for any further call to the method.

Upvotes: 8

Related Questions