How to Use Argumentcaptor for Stubbing

How to use ArgumentCaptor for stubbing?

Assuming the following method to test:

public boolean doSomething(SomeClass arg);

Mockito documentation says that you should not use captor in this way:

when(someObject.doSomething(argumentCaptor.capture())).thenReturn(true);
assertThat(argumentCaptor.getValue(), equalTo(expected));

Because you can just use matcher during stubbing:

when(someObject.doSomething(eq(expected))).thenReturn(true);

But verification is a different story. If your test needs to ensure that this method was called with a specific argument, use ArgumentCaptor and this is the case for which it is designed:

ArgumentCaptor<SomeClass> argumentCaptor = ArgumentCaptor.forClass(SomeClass.class);
verify(someObject).doSomething(argumentCaptor.capture());
assertThat(argumentCaptor.getValue(), equalTo(expected));

Mockito ArgumentCaptor needs stubbing even I use verify

The problem lies in the following lines:

  Quantity updated = saveQuantity(quantity, request);
return CommandDTO.builder().uuid(updated.getUuid()).build();

Which is essentially the same as:

 Quantity updated = quantityRepository.save(quantity)
return CommandDTO.builder().uuid(updated.getUuid()).build();

The stubbing is necessary, because you're expecting the save method to return something, when you call updated.getUuid().
Without the stub, updated is null and your call results in a NullPointerException.

Proper usage of mockito ArgumentCaptor in Java?

Eugene is right, you don't need an ArgumentCaptor. To answer the question of when you need it: if you want to verify the value of a transatory object you don't have access to before or after your method.

For example, in

boolean createAndSave(String productName) {
Product p = new Product(productName);
return repository.save(p);
}

you don't have access to the created Product but want to verify it was created correctly. To do this, you can capture it:

ArgumentCaptor<Product> savedCaptor = ArgumentCaptor.forClass(Product.class);
service.createAndSave("name");
verify(repository).save(savedCaptor.capture()); // get the product being saved
Product saved = savedCaptor.getValue();
assertEqual("name", saved.getName());

Now, you make sure that the repository was used to save a product with the name you gave the service.

In your case, you can just use when(repository.save(any()).thenReturn(product) with a product you created ahead of time.

How to capture method arguments sent to a stubbed method using Mockito

final ArgumentCaptor<String> arg1Captor = ArgumentCaptor.forClass(String.class);
final ArgumentCaptor<Object> arg2Captor = ArgumentCaptor.forClass(Object.class);
final ArgumentCaptor<Class<?>> arg3Captor = ArgumentCaptor.forClass(Class.class);

Mockito.verify(restTemplateMock).postForEntity(arg1Captor, arg2Captor, arg3Captor);

Assert.assertEquals("Whatever", arg1Captor.getValue());

capture parameters passes to stub in powermockito

After the call to verifyStatic, you'll need to actually call the method you're trying to verify, as in the documentation here:

PowerMockito.verifyStatic(Static.class);
Static.thirdStaticMethod(Mockito.anyInt());

At that point you can use Mockito argument captors, as demonstrated (but not tested):

ArgumentCaptor<Properties> propertiesCaptor =
ArgumentCaptor.forClass(Properties.class);

PowerMockito.verifyStatic(SomeStaticClass.class);
SomeStaticClass.methodBeingStubbed(propertiesCaptor.capture());

Properties passedInValue = propertiesCaptor.getValue();

If you're used to @Mock annotations, or you need to capture a generic (as in List<String>), you may also be interested in using the @Captor annotation instead.

How to use ArgumentCaptor to verify bytes written to HttpServletResponse

One way to do this would be to mock both response and its output stream, then verify calls to the write method of your mocked output stream.

Can Mockito capture arguments of a method called multiple times?

I think it should be

verify(mockBar, times(2)).doSomething(...)

Sample from mockito javadoc:

ArgumentCaptor<Person> peopleCaptor = ArgumentCaptor.forClass(Person.class);
verify(mock, times(2)).doSomething(peopleCaptor.capture());

List<Person> capturedPeople = peopleCaptor.getAllValues();
assertEquals("John", capturedPeople.get(0).getName());
assertEquals("Jane", capturedPeople.get(1).getName());


Related Topics



Leave a reply



Submit