Use Mockito to verify that nothing is called after a method

I'm using Mockito to write a unit test in Java, and I'd like to verify that a certain method is the last one called on an object.

I'm doing something like this in the code under test:

row.setSomething(value);
row.setSomethingElse(anotherValue);
row.editABunchMoreStuff();
row.saveToDatabase();

In my mock, I don't care about the order in which I edit everything on the row, but it's very important that I not try to do anything more to it after I've saved it. Is there a good way to do this?

Note that I'm not looking for verifyNoMoreInteractions: it doesn't confirm that saveToDatabase is the last thing called, and it also fails if I call anything on the row that I don't explicitly verify. I'd like to be able to say something like:

verify(row).setSomething(value);
verify(row).setSomethingElse(anotherValue);
verifyTheLastThingCalledOn(row).saveToDatabase();

If it helps, I'm switching to Mockito from a JMock test that did this:

row.expects(once()).method("saveToDatabase").id("save");
row.expects(never()).method(ANYTHING).after("save");

Solution 1:

I think it requires more custom work.

verify(row, new LastCall()).saveToDatabase();

and then

public class LastCall implements VerificationMode {
    public void verify(VerificationData data) {
        List<Invocation> invocations = data.getAllInvocations();
        InvocationMatcher matcher = data.getWanted();
        Invocation invocation = invocations.get(invocations.size() - 1);
        if (!matcher.matches(invocation)) throw new MockitoException("...");
    }
}

Previous Answer:

You are right. verifyNoMoreInteractions is what you need.

verify(row).setSomething(value);
verify(row).setSomethingElse(anotherValue);
verify(row).editABunchMoreStuff();
verify(row).saveToDatabase();
verifyNoMoreInteractions(row);

Solution 2:

Not 100% on topic but I was just looking to find the opposite of verify, and this was the only relevant result, it ends up I was after Mockito.verifyZeroInteractions(mock);

Just incase anyone else ends up here looking for this...

Solution 3:

This question led me to make some enhancements to the Verifications API in JMockit (available in the upcoming release 0.983).

The solution I came up with allows you to write (in a test method):


    new VerificationsInOrder() {{
        unverifiedInvocations();
        row.saveToDababase();
    }};

... if you only want to verify that a certain method is called after everything else. To verify it happens before all other invocations, simply move the call to the top. This actually applies to any sequence of consecutive invocations.

If in addition to the above verification, you also want to verify that some other methods are called in any order, a second verifications block can be added to the test (before or after the other block, it doesn't matter):


    new Verifications() {{
        row.setSomething(value);
        row.setSomethingElse(anotherValue);
    }};

Although a bit long because of the use of anonymous inner classes, this syntax is both simple and flexible; notice how it adds structure to the test and avoids the repetition of method calls (like verify(...)). There is more to it than I described here (Hamcrest matchers, invocation counts, etc.), and it's not limited to the verification of instance methods (static methods and constructors can be mocked and verified in the same way).