【问题标题】:How to verify method is only ever called with expected arguments?如何验证仅使用预期参数调用方法?
【发布时间】:2012-12-24 17:50:07
【问题描述】:

我想验证对模拟的调用只会发生在某些预期的参数值上,而不会发生在其他任何情况下。

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 会失败,但测试却通过了。如果方法只接受一个参数,这将按预期工作。

【问题讨论】:

    标签: java unit-testing junit mocking mockito


    【解决方案1】:

    这是一个逻辑错误。

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

    因此,这符合我的要求:

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

    【讨论】:

      【解决方案2】:

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

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

      或者,你可以写

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

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

      【讨论】:

      • 我更喜欢这个,但它似乎不适用于我的示例。也许是我不止一次调用方法的事实? (见“atLeastOnce”);
      • 好的,然后输入atLeastOnce()。我没有费心输入,因为从您的问题中可以清楚地看出您已经知道如何使用atLeastOnce()
      • 不,我的意思是它实际上不起作用,当我将代码插入到我的示例中时,然后 both 测试都失败了...在进一步检查你的第一个snippit 确实 似乎可以按需要工作。这只是第二个不起作用的片段。
      • 真的吗?好的,我会重新测试它并尝试找出发生了什么。但这不会是今天;我很忙。
      • 我无法使用解决方案 1,因为我需要与 mock 上的其他方法进行交互。由于某种原因,解决方案 2 不起作用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-18
      • 2020-06-06
      • 1970-01-01
      • 2021-07-24
      • 2014-08-13
      • 1970-01-01
      相关资源
      最近更新 更多