Imagine you have these two classes:
public static class Manager {
private Worker Worker = new Worker();
public void dailyWork() {
System.out.println("Good morning");
String msg = RandomStringUtils.randomAlphabetic(10);
Worker.echoTwice(msg);
System.out.println("See you tomorrow");
}
public void setWorker(Worker Worker) {
this.Worker = Worker;
}
public Worker getWorker() {
return Worker;
}
}
public static class Worker {
public String echoTwice(String msg) {
return msg + "-" + msg;
}
}
And you are integation testing the Manager class. How can you extract the arguments and returned values of Worker.echoTwice() ? You can create a subclass of Worker and inject an instance of it to Manager. However, this is not so "clean".
Another way of doing this is to leverage Mockito’s "Answer" feature
@Test
public void test() {
Manager manager = new Manager();
Worker stubbedWorker = spy(manager.getWorker());
manager.setWorker(stubbedWorker);
final List<String> argumentBag = new ArrayList<String>();
final List<String> returnedValueBag = new ArrayList<String>();
doAnswer(invocation -> {
argumentBag.add(invocation.getArgumentAt(0, String.class));
String returnedValue = (String)invocation.callRealMethod();
returnedValueBag.add(returnedValue);
return returnedValue;
}).when(stubbedWorker).echoTwice(Mockito.anyString());
manager.dailyWork();
System.out.println(argumentBag.get(0));
System.out.println(returnedValueBag.get(0));
}