简体   繁体   中英

How to verify method is only ever called with expected arguments?

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.

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM