How do I use MockitoAnnotations and @Captor?


77
views
0
7 months ago by

Does the @Captor annotation make life any simpler when setting up captors in unit tests?

add commentfollow this post modified 4 months ago by robert bailes   • written 7 months ago by Graham Trott  

2 Answers


0
7 months ago by

MockitoAnnotations allow you to declare all your captors at the head of your test class, then just use them where needed rather than declaring/initialising them each time. They also permit you to setup a captor for a generic item such as a list, where the traditional approach doesn't work because there are no separate classes for generics.

Using DefaultBookingCommandServiceTest as an example, under all the variable declarations is a set of captor definitions:

    @Captor
    private ArgumentCaptor<String> stringCaptor;
    @Captor
    private ArgumentCaptor<BigDecimal> bigDecimalCaptor;
    @Captor
    private ArgumentCaptor<List<String>> listOfStringCaptor;
    @Captor
    private ArgumentCaptor<TypedMessage> typedMessageCaptor;

These just declare the captor types; the neat part is that they are all initialised together using a single command:

    MockitoAnnotations.initMocks(this);

which is placed in setup(). Now all that's needed in the actual test is

    verify(bookingService).switchBookingBookerToOrgOwner(stringCaptor.capture(), eq(userId.toString()));
    assertEquals(bookingQm.getId(), stringCaptor.getValue());

We might consider creating an abstract parent class along the lines of

public class AbstractUnitTest {

    @Captor
    protected ArgumentCaptor<String> stringCaptor;
    @Captor
    protected ArgumentCaptor<BigDecimal> bigDecimalCaptor;
    @Captor
    protected ArgumentCaptor<List<String>> listOfStringCaptor;
    @Captor
    protected ArgumentCaptor<TypedMessage> typedMessageCaptor;

    protected void setup() {
        MockitoAnnotations.initMocks(this);
    }
}

and putting all the captor definitions we'll ever need into it. Then each unit test can be reparented onto this class and the first line of its setup() method will read

    super.setup();

It's likely that a parent class of this type would gradually fill up with useful methods, avoiding a certain amount of repetition.

add comment modified 7 months ago by Graham Trott   • written 7 months ago by Graham Trott  
0
4 months ago by

Don't use 

MockitoAnnotations.initMocks(this);

Any occurrences of the above should be replaced with either

@RunWith(PowerMockRunner.class)

or

@RunWith(MockitoJUnitRunner.class)

as both will reset the mocks in between tests and they do not mess up the mock implementations if the additional features of PowerMock are required.

add comment written 4 months ago by robert bailes  
Please log in to add an answer/comment or follow this question.

Share this question


Similar posts:
Search »