Collect an inner method’s arguments and returned values with Mockito in integration tests

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