1

I'd like to verify that calls against a mock only ever happen with some expected argument values, and never with anything else.

public interface ADependancy {
 public void method(String parameter, String otherParameter);
}
public class Foo {
 private ADependancy myHelper;
 public Foo(ADependancy helper) {
 this.myHelper = helper;
 }
 public void good() {
 myHelper.method("expected","expected");
 myHelper.method("expected","expected");
 myHelper.method("expected","expected");
 }
 public void bad() {
 myHelper.method("expected","expected");
 myHelper.method("expected","UNexpected");
 myHelper.method("expected","expected");
 }
}

I tried this:

public class FooTest extends TestCase {
 private ADependancy mock =mock(ADependancy.class);;
 private Foo foo = new Foo(mock);
 @Test
 public void testGood() {
 foo.good();
 validateOnlyCalledWithExpected();
 }
 @Test
 public void testBad() {
 foo.bad();
 validateOnlyCalledWithExpected();
 }
 private void validateOnlyCalledWithExpected() {
 verify(mock,atLeastOnce()).method(eq("expected"),eq("expected"));
 verify(mock,never()).method(not(eq("expected")),not(eq("expected")));
 }
}

Expecting testBad to fail, but instead the test passes. If method only takes one parameter, this works as expected.

asked Dec 24, 2012 at 17:50

2 Answers 2

4

It was a logic mistake.

I wanted to assert that each argument is never anything but the expected value. But instead, what I was actually asserting was that it never happens that they are ALL not the expected value. So with the way I had it, it did not fail as desired, because in fact, some of the arguments are not not the expected value, therefore the method is never called with all the parameters not the expected value, and the verify passes.

Thus, this works for what I wanted:

 private void validateOnlyCalledWithExpected() {
 verify(mock,atLeastOnce()).method(eq("expected"),eq("expected"));
 verify(mock,never()).method(not(eq("expected")),anyString());
 verify(mock,never()).method(anyString(),not(eq("expected")));
 }
answered Dec 24, 2012 at 17:50
Sign up to request clarification or add additional context in comments.

Comments

4

You could use the verifyNoMoreInteractions static method, documented at http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#finding_redundant_invocations.

verify(mock).method(eq("expected"),eq("expected"));
verifyNoMoreInteractions(mock);

Alternatively, you could write

verify(mock).method(eq("expected"),eq("expected"));
verify(mock,never()).method(anyString(),anyString());

because the second call to verify will disregard the calls that have already been verified.

answered Dec 24, 2012 at 22:24

6 Comments

I'd like this better, but it doesn't seem to work for my example. Perhaps it is the fact that I am calling method more than once? (See the "atLeastOnce" );
OK, then put the atLeastOnce() in. I didn't bother typing that because it was clear from your question that you already knew how to use atLeastOnce().
No, I meant that it literally doesn't work, when I plug in you code to my example, then both tests fail... OK upon further inspection your first snippit does appear to work as desired. It is just second snippit which doesn't work.
Really? OK, I'll re-test it and try to find out what's going on. This won't be today though; I'm busy.
I was not able to go with solution 1 since I need to interact with other methods on the mock. And solution 2 did not work for some reason.
|

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.