0

Is there any way to setup JMock's onConsecutiveCalls method to loop back to the first Action passed once it reaches the end of the list of parameters passed? In the sample code below, I would like the mock to return true->false->true->Ad infinitum.

Mock setup:

final MyService myServiceMocked = mockery.mock(MyService.class);

mockery.checking(new Expectations() {{  
  atLeast(1).of(myServiceMocked).doSomething(with(any(String.class)), with(any(String.class))); 
  will (onConsecutiveCalls(
    returnValue(true),
    returnValue(false)
  ));
}});

Method calling doSomething method:

...
for (String id:idList){
  boolean first = getMyService().doSomething(methodParam1, someString);
  boolean second =  getMyService().doSomething(anotherString, id);
}
...
4

1 回答 1

0

I got around this issue by adding the following to my test class, then calling onRecurringConsecutiveCalls() in place of onConsecutiveCalls().

Additional code:

/**
 * Recurring version of {@link org.jmock.Expectations#onConsecutiveCalls(Action...)}
 * When last action is executed, loops back to first.
 * @param actions Actions to execute.
 * @return An action sequence that will loop through the given actions.
 */
public Action onRecurringConsecutiveCalls(Action...actions) {
    return new RecurringActionSequence(actions);
}
/**
 * Recurring version of {@link org.jmock.lib.action.ActionSequence ActionSequence}
 * When last action is executed, loops back to first.
 * @author AnthonyW
 */
public class RecurringActionSequence extends ActionSequence {
    List<Action> actions;
    Iterator<Action> iterator;

    /**
     * Recurring version of {@link org.jmock.lib.action.ActionSequence#ActionSequence(Action...) ActionSequence}
     * When last action is executed, loops back to first.
     * @param actions Actions to execute.
     */
    public RecurringActionSequence(Action... actions) {
        this.actions = new ArrayList<Action>(Arrays.asList(actions));
        resetIterator();
    }

    @Override
    public Object invoke(Invocation invocation) throws Throwable {
        if (iterator.hasNext()) 
            return iterator.next().invoke(invocation);
        else
            return resetIterator().next().invoke(invocation);
    }

    /**
     * Resets iterator to starting position.
     * @return <code>this.iterator</code> for chain calls.
     */
    private Iterator<Action> resetIterator() {
        this.iterator = this.actions.iterator();
        return this.iterator;
    }
}

Note: This code is based on the source code from JMock 2.1.

于 2013-07-03T17:39:15.787 回答