Capturing and asserting the argument

In this recipe, we will capture an argument passed to the mock's method to perform further verification.

Getting ready

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);
    }

}

How to do it...

To create ArgumentCaptor that will contain the captured argument, you have to perform the following steps:

  1. Annotate your test with @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).
  2. Create a field of the ArgumentCaptor type and annotate it with the @Captor annotation.
  3. To use the capturing of arguments, you have to verify a method and provide the 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.

  4. Now you can retrieve the last passed value with the following code:
    argumentCaptor.getValue()
  5. You can get all of the captured values (if the method was executed multiple times) by calling the following method:
    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");
    }
  
}

How it works...

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.

See also

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.52.188