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
Can't Find/Install Libxtst.So.6
Java 8: How to Work with Exception Throwing Methods in Streams
What Is the Purpose of Accesstype.Field, Accesstype.Property and @Access
Is There a Priorityqueue Implementation with Fixed Capacity and Custom Comparator
How to Disable Loggers of a Class or of Whole Package
Displaying Am and Pm in Lower Case After Date Formatting
How to Convert Int[] to Byte[]
How to Change Java Logging Console Output from Std Err to Std Out
What Is the Time Complexity Performance of Hashset.Contains() in Java
How to Display Bar Value on Top of Bar Javafx
Determining Current Call Stack (For Diagnostic Purposes)
How to Read Excel Cell Having Date with Apache Poi
Byte Array to Short Array and Back Again in Java
Javac Error: Class Names Are Only Accepted If Annotation Processing Is Explicitly Requested
Spring Web MVC - Validate Individual Request Params
How to Extract Parameters from a Given Url
Enable Partial Compilation in Intellij Idea
Why Can't You Reduce the Visibility of a Method in a Java Subclass