Java 如何使用ArgumentCaptor进行存根?
在Mockito,上面写着 建议将ArgumentCaptor与验证一起使用,但不与存根一起使用Java 如何使用ArgumentCaptor进行存根?,java,unit-testing,junit,mockito,Java,Unit Testing,Junit,Mockito,在Mockito,上面写着 建议将ArgumentCaptor与验证一起使用,但不与存根一起使用 但我不明白ArgumentCaptor怎么能用来打存根。是否有人可以解释上述语句,并说明ArgumentCaptor如何用于存根,或提供一个链接,说明如何进行存根?假设使用以下方法进行测试: public boolean doSomething(SomeClass arg); Mockito文档指出,您不应该以这种方式使用captor: when(someObject.doSomething(ar
但我不明白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));
ArgumentCaptor ArgumentCaptor=ArgumentCaptor.forClass(SomeClass.class);
验证(someObject).doSomething(argumentCaptor.capture());
assertThat(argumentCaptor.getValue(),equalTo(预期));
线路
when(someObject.doSomething(argumentCaptor.capture())).thenReturn(true);
我也会这样做
when(someObject.doSomething(Matchers.any())).thenReturn(true);
因此,在存根时使用argumentCaptor.capture()没有任何附加值。使用Matchers.any()可以更好地显示实际发生的情况,因此可读性更好。
使用argumentCaptor.capture(),您无法读取真正匹配的参数。
当您有更多信息(预期参数的类)时,您可以使用更具体的匹配器来改进测试,而不是使用any()
还有一个问题:
如果在存根时使用argumentCaptor.capture(),则不清楚验证后应捕获多少值。我们希望在验证期间捕获值,而不是在存根期间,因为此时还没有要捕获的值。那么,在存根过程中,参数捕获器捕获方法捕获了什么呢?它捕获任何东西,因为还没有什么可以捕获。
我认为这是一个未定义的行为,我不想使用未定义的行为。假设,< p>,如果搜索发现你在这个问题上,那么你可能想要这个:
doReturn(someReturn).when(someObject).doSomething(argThat(argument -> argument.getName().equals("Bob")));
为什么??因为像我一样,你重视时间,你不会仅仅为了单个测试场景而实现.equals
99%的测试会因模拟返回的null而崩溃,在合理的设计中,您将不惜一切代价避免返回
null
,使用Optional
或移动到Kotlin。这意味着不需要经常使用verify
,而ArgumentCaptor编写起来太乏味了。谢谢您的回答。我有个问题。在第三个代码块中,我们知道只有当预期值传递给doSomething时,才会返回true。但第二个代码块何时返回true?或者在这种情况下,someObject是否总是为someMethod返回true?嗯,我相信您的意思是“但是第三个代码块何时返回true?”。在第三个代码块中,我们不关心返回值,而是让它成为默认值。对于布尔值,它是false
,而不是true
。不,我将所有灰色背景块计算为代码块。包括第一艘班轮。当(someObject.doSomething(argumentCaptor.capture()).thenReturn(true)时,我指的是这一行;啊,对不起。是的,在这种情况下,将始终返回true。不确定“不与存根一起使用”的原因是否简单。matchers不给我们实际的预期参数(只是类型),尽管参数可能是错误的,但会导致测试通过。这里的解释非常简短和好:回答您的问题,argumentCaptor。capture()会捕获传递给存根方法的值,这对于以下情况非常有用:“someObject.doSomething(新的OtherObject(4))”在这种情况下,捕获者将获得OtherObject实例,然后您可以使用该实例验证是否存在4passed@raspacorpargumentCaptor.capture()在vertification方法中使用时捕获传递给stubbed方法的值。在stubing(当方法)中使用时不捕获因为当时没有要捕获的内容(要测试的逻辑尚未调用)。