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)); }