如何验证方法只能使用预期的参数调用?

时间:2012-12-24 17:50:07

标签: java unit-testing junit mocking mockito

我想验证针对模拟的调用是否只发生在某些预期的参数值上,而且从不与其他任何内容发生。

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

我试过了:

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

期望testBad失败,但测试通过了。如果method只接受一个参数,则按预期工作。

2 个答案:

答案 0 :(得分:4)

这是一个逻辑错误。

我想断言每个参数绝不是预期值。 但相反,我实际上断言的是,它永远不会发生,它们都不是预期的价值。 因此,按照我的方式,它没有按照需要失败,因为事实上,某些参数不是期望值,因此方法永远所有调用参数而不是期望值,并且验证通过。

因此,这适用于我想要的东西:

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

答案 1 :(得分:4)

您可以使用http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#finding_redundant_invocations中记录的verifyNoMoreInteractions静态方法。

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

或者,你可以写

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

因为对verify的第二次调用将忽略已经验证过的电话。