In this recipe, we will capture an argument passed to the mock's method to perform further verification.
For this recipe, our system under test will be a TaxTransferer
class that will prepare the person to be sent through the web service by marking him a Polish citizen. Only if the person is not null, the transfer of tax will take place. Let's also assume that it is absolutely crucial for us to make sure that the person that we send via the web service contains very specific data:
public class TaxTransferer { static final String POLAND = "Poland"; private final TaxService taxService; public TaxTransferer(TaxService taxService) { this.taxService = taxService; } public void transferTaxFor(Person person) { if (person == null) { return; } taxService.transferTaxFor(makePersonPolish(person)); } private Person makePersonPolish(Person person) { return new Person(person, POLAND); } }
To create ArgumentCaptor
that will contain the captured argument, you have to perform the following steps:
@RunWith(MockitoJUnitRunner.class)
for JUnit or @Listeners(MockitoTestNGListener.class)
for TestNG (check Chapter 1, Getting Started with Mockito, for more details on the TestNG configuration).ArgumentCaptor
type and annotate it with the @Captor
annotation.capture()
method of ArgumentCaptor
as its parameter, as shown in the following code:verify(mock).methodToVerify(argumentCaptor.capture());
If this procedure is followed, your captor will contain the captured arguments.
argumentCaptor.getValue()
argumentCaptor.getAllValues()
The following code represents the JUnit test with an example of ArgumentCaptor
(I'm using the BDDMockito.given(...)
static import):
@RunWith(MockitoJUnitRunner.class) public class TaxTransfererTest { @Mock TaxService taxService; @InjectMocks TaxTransferer systemUnderTest; @Captor ArgumentCaptor<Person> personCaptor; @Test public void should_change_persons_country_before_sending_data_through_ws() { // when systemUnderTest.transferTaxFor( new Person("Lewandowski", "UK")); // then verify(taxService).transferTaxFor(personCaptor.capture()); then(personCaptor.getValue()).hasName("Lewandowski").hasCountry("Poland"); } }
When you call argumentMatcher.capture()
, Mockito registers a special implementation of the Mockito ArgumentMatcher
—the CapturingMatcher
. This matcher stores the passed argument values for later use. When you call either getAllValues()
or getValue()
, Mockito retrieves the data stored in that matcher.
3.145.52.188