Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用ArgumentCaptor进行存根?_Java_Unit Testing_Junit_Mockito - Fatal编程技术网

Java 如何使用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

在Mockito,上面写着

建议将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));
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(当方法)中使用时不捕获因为当时没有要捕获的内容(要测试的逻辑尚未调用)。