sonoerin
sonoerin

Reputation: 5175

Mocking a return value

I am using Mockito 1.9.5 to try and test a method. Here is the method:

@Autowire
AuditLogRepository auditlogRepository;

//method stuff abbreviated out

if (authentic.isAuthorized()) {
    menuService.updateUserWithMenu( authentic );
    AuditLog auditor = Helper.buildAuditor( authentic );
    auditor.setAccessPoint( request.getRequestURL().toString() );
    ....
    AuditLog createdAuditLog = auditlogRepository.save( auditor );
    logger.debug( "Created AuditLog id = " + createdAuditLog.getID() );
    ...

}

And here is how I am trying to test it:

@InjectMocks
LoginController loginController;

@Mock
AuditLog aLog;

@Mock
AuditLog createdAuditLog;

@Mock
AuditLogRepository auditlogRepositoryMock;

@Before
public void setUp() {
    MockitoAnnotations.initMocks( this );
    this.mockMvc = MockMvcBuilders.standaloneSetup( loginController ).build();
}

@Test    
public void testLogin() throws Exception {
    ...
    AuditLog aLog = mock( AuditLog.class );
    when( auditlogRepositoryMock.save( aLog ) ).thenReturn(createdAuditLog );
    when( createdAuditLog.getID() ).thenReturn( new Long( 1 ) );

It looks like no matter what I do, Mockito will always return null, except for primitives. But my code is going to act upon a returned value. So my question is there a way to test this without getting the null pointer? Can Mockito return an object from a method call?

Upvotes: 0

Views: 1782

Answers (2)

matsev
matsev

Reputation: 33759

Can Mockito return an object from a method call?

Yes, you can change the Answers of the @Mock annotation from the default values null to return mocks, stubs, call the real methods or other behaviour, e.g.

@Mock(answer = RETURNS_MOCKS)
AuditLogRepository auditlogRepositoryMock;

Upvotes: 0

Don Roby
Don Roby

Reputation: 41137

You have mocks for AuditLog as both a field and a local variable in your test, and I suspect neither is actually used in the code under test, since the AuditLog instance passed to your auditlogRepositoryMock.save call is actually created in the code under test by the call

AuditLog auditor = Helper.buildAuditor( authentic );

If you need to really control this argument from your test, you might need to change the code you're testing to allow that.

If you don't really care about the value of the AuditLog passed in, you can change your stub to use a more permissive Matcher, possibly something like:

when( auditlogRepositoryMock.save( argThat(any(AuditLog.class)) ) ).thenReturn(createdAuditLog );

which should cause your repository mock to return the test value createdAuditLog for all calls of save.

Upvotes: 1

Related Questions