如何使用ArgumentCaptor进行存根



在Mockito文档和javadocs中,它说

建议使用ArgumentCaptor进行验证,但不要使用存根。

但我不明白ArgumentCaptor怎么能用于存根。有人能解释以上陈述并展示ArgumentCaptor如何用于存根吗?或者提供一个链接来展示如何进行存根?

假设以下方法进行测试:

public boolean doSomething(SomeClass arg);

Mockito文档说你应该而不是以这种方式使用captor:

when(someObject.doSomething(argumentCaptor.capture())).thenReturn(true);
assertThat(argumentCaptor.getValue(), equalTo(expected));

因为你可以在存根期间使用matcher:

when(someObject.doSomething(eq(expected))).thenReturn(true);

但核查是另一回事。如果您的测试需要确保使用特定的参数调用此方法,请使用ArgumentCaptor,这就是它的设计情况:

ArgumentCaptor<SomeClass> argumentCaptor = ArgumentCaptor.forClass(SomeClass.class);
verify(someObject).doSomething(argumentCaptor.capture());
assertThat(argumentCaptor.getValue(), equalTo(expected));

假设,如果搜索让你找到了这个问题,那么你可能想要这个:

doReturn(someReturn).when(someObject).doSomething(argThat(argument -> argument.getName().equals("Bob")));

为什么?因为和我一样,您重视时间,不会仅仅为了单个测试场景而实现.equals

99%的测试都会因Mock返回的null而失败,在合理的设计中,您将不惜一切代价避免返回null,使用Optional或转移到Kotlin。这意味着verify不需要经常使用,而且ArgumentCaptors编写起来太乏味了。

when(someObject.doSomething(argumentCaptor.capture())).thenReturn(true);

会和一样

when(someObject.doSomething(Matchers.any())).thenReturn(true);

因此,在存根时使用argumentCaptor.capture()没有任何附加值。使用Matchers.any()可以更好地显示实际发生的事情,因此可读性更好。使用argumentCaptor.capture(),您无法读取哪些参数真正匹配。当您有更多信息(预期参数的类)时,您可以使用更具体的匹配器来改进测试,而不是使用any()。

还有另一个问题:如果在存根时使用argumentCaptor.capture(),则不清楚在验证后应该捕获多少值。我们希望在验证期间捕获一个值,而不是在存根处理期间捕获,因为此时还没有要捕获的值。那么,在存根期间,参数捕获器捕获方法捕获了什么呢?它捕捉任何东西,因为还没有什么可捕捉的。我认为这是未定义的行为,我不想使用未定义行为。

相关内容

  • 没有找到相关文章

最新更新