参数捕获器(ArgumentCaptor)

AgrumentCaptor是在org.mockito包中定义的类。它用于捕获参数值以进行进一步的声明。我们将参数捕获器与诸如verify()或then()之类的方法结合使用, 以获取调用特定方法时传递的值。
下面列出了ArgumentCaptor类的一些重要方法:

方法类型和方法名称 描述
T capture() 它用于捕获方法参数。
ArgumentCaptor < U> forClass(类< S> clazz) 它用于构建新的ArgumentCaptor。
List < T> getAllValues() 它用于返回所有捕获的值。
T getValue() 它用于返回参数的所有捕获值。
建议将ArgumentCaptor用于验证, 但不能用于存根。因为通过存根, 它会降低测试的可读性, 因为捕获程序是在assert(验证或随后)块之外定义的。
ArgumentCaptor的示例
在这里, 我们将使用BDD样式创建一个ArgumentCapture示例。在此示例中, 我们使用then()。should()方法, 而不使用BDDMockito类中可用的verify()方法。使用它们的主要目的是使代码更具可读性和可理解性。
步骤1:创建一个名为ToDoService的接口, 其中包含两个未实现的方法。
ToDoService.java
import java.util.List; public interface ToDoService { public List< String> getTodos(String user); public void deleteTodos(String doString); }

步骤2:创建名为ToDoBusiness的ToDoService接口的实现类。
【参数捕获器(ArgumentCaptor)】ToDoBusiness.java
import java.util.ArrayList; import java.util.List; // ToDoBusiness is a SUT (system under test) // ToDoService is a Dependency (as ToDoBusiness is dependent on it)public class ToDoBusiness { public ToDoService doService; public ToDoBusiness(ToDoService doService) {this.doService = doService; }public void deleteTodosNotRelatedToHibernate(String user) {List< String> Combinedlist = doService.getTodos(user); for(String todos:Combinedlist) {if(!todos.contains("Hibernate")) {doService.deleteTodos(todos); }} } }

步骤3:创建一个名为ToDoBusinessMock的模拟类以进行测试。在这里, 我们声明了一个ArgumentCaptor, 它在调用deleteTodos()方法时捕获此(todoService)模拟的参数。
ToDoBusinessMock.java
import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.then; import static org.mockito.Mockito.mock; import java.util.Arrays; import java.util.List; import org.junit.Test; import org.mockito.ArgumentCaptor; public class ToDoBusinessMock { @Test public void deleteTodosusing_BDD_usingArgumentCaptor() {//Declare an Argument Captor ArgumentCaptor< String> argumentCaptor = ArgumentCaptor.forClass(String.class); //Given ToDoService todoService = mock(ToDoService.class); List< String> combinedlist = Arrays.asList("Use Hibernate Java", "Use Hibernate Core", "Use Hibernate", "Use Spring MVC"); given(todoService.getTodos("dummy")).willReturn(combinedlist); ToDoBusiness business = new ToDoBusiness(todoService); //When business.deleteTodosNotRelatedToHibernate("dummy"); //Then then(todoService).should().deleteTodos(argumentCaptor.capture()); assertThat(argumentCaptor.getValue(), is("Use Spring MVC")); } }

在上面的代码中, 我们已经捕获了参数, 并使用getValue()方法检查了传递的参数是否为” Use Spring MVC” 。
输出如下
参数捕获器(ArgumentCaptor)

文章图片
考虑一个场景, 我们要同时删除多个值。在这种情况下, 将使用名为getAllValues()的方法, 如下所示。
then(todoService).should().deleteTodos(argumentCaptor.capture()); assertThat(argumentCaptor.getAllValues().size(), is(2));

但是上面的代码将引发异常, 如下所示。
参数捕获器(ArgumentCaptor)

文章图片
要删除上述异常, 我们需要指定该方法应被调用的次数。假设列表中有两个非Hibernate项可用, 因此我们需要两次调用该方法, 如下所示。
then(todoService).should(times(2)).deleteTodos(argumentCaptor.capture()); assertThat(argumentCaptor.getAllValues().size(), is(2));

输出如下
参数捕获器(ArgumentCaptor)

文章图片

    推荐阅读