Another difficult problem when testing using mocks is how to mock function calls which modify the parameters passed in. Turns out you can actually do this using nearly the same technique. The InvocationOnMock parameter passed in can be interrogated to find the parameters passed in and then the parameters can be altered.
My case was even worse as I needed the parameter to a void function to be modified but it turns out the same technique works.
To do this you use the doAnswer() function but you use it with a void
doAnswer( new Answer<Void>) ...
What I was trying to do was to test a function which called a JpaRepository<>.save() method and then returned the auto-generated ID from within the modifed entity.
So the example looks like this:
doAnswer(new Answer<Void>()
{
@Override
public Void answer(InvocationOnMock invocation)
throws Throwable
{
Object[] arguments = invocation.getArguments();
if ( arguments != null
&&
arguments.length > 0
&&
arguments[0] != null)
{
SomeEntity entity = (SomeEntity) arguments[0];
entity.setId(testInternalId);
}
return null;
}
}).when(mockRepository).save(any(SomeEntity.class));