cclark
cclark

Reputation: 1412

Can Mockito return an argument to a method AFTER calling a method on it?

I'm new to Mockito and trying to write tests for some legacy code before I start a large refactoring and have come across the following pattern which I expect to see regularly in the code base:

...
Foo foo = new Foo(bar, baz);
foo = db.persist(foo); // Save an object to the DB and have the id set
FooTO fooTO = convert(FooTO.class, foo); // Turn foo entity into a foo Transfer Object
Response response = createdResponse(fooTO, foo.getId()); // Prepare a 201 response
return response;

The problem I'm facing is in a normal call to db.persist() the id will be set after successfully persisting the foo entity object. But under test that field is null and I end up getting a NPE in the createdResponse call.

I'm already using the following in my test:

Db db = Mockito.mock(Db.class);
when(db.persist(any(Foo.class))).then(returnsFirstArg());

But I'd like to be able to call setId(100) or similar on that foo argument before it is returned.

Does anyone have insights on how to approach this?

Should I be looking to fake out the call to createdResponse instead?

Upvotes: 1

Views: 1719

Answers (1)

denis.solonenko
denis.solonenko

Reputation: 11765

You can use when...thenAnswer to set the id on foo:

when(db.persist(any(Foo.class))).thenAnswer(new Answer<Foo>() {
    @Override
    public Foo answer(InvocationOnMock invocation) throws Throwable {
        Foo foo  = (Foo) invocation.getArguments()[0];
        foo.setId(100);
        return foo;
    }
});

Upvotes: 8

Related Questions