Home > Software engineering >  How to get the value of a mock service with Mockito and Spring
How to get the value of a mock service with Mockito and Spring

Time:10-14

How can I capture the value of an operation on a mock repository, as apposed to overriding the return value.

Take for example this test

@Mock
AccountRepository accountRepository;

@InjectMocks
AccountService accountService;

@Test
public void remove_staff_updates_roles() {

    Account account = new Account("username", "pass");

    when(accountRepository.findByUsername(any(String.class))).thenReturn(Optional.of(account));

    accountService.updateStaffStatusByUsername("user", false);

    // How can I capture the account that is to be saved here?

    assertFalse(????.getValue().getRoles().contains(Role.ROLE_STAFF));
    }

Then in the service

public Account updateStaffStatusByUsername(String username, Boolean toState) {
    Account account;

    if (toState) {
        return addRole(username, Role.ROLE_STAFF);
    }
    return removeRole(username, Role.ROLE_STAFF);
    
}

Account addRole(String username, Role role) {
    Optional<Account> optionalAccount = accountRepository.findByUsername(username);

    if (account.isEmpty()) {
        throw new CustomException("No account exists with the username: "   username, HttpStatus.NOT_FOUND);
    }

    Account account = optionalAccount.get();
    account.addRole(role);

    // I want to intercept this and take the value to evaluate
    return accountRepository.save(account);
}

I want to verify that the state of the account has changed correctly when the service is to save the updated account.

CodePudding user response:

As here you are passing Account (Optional) class object account in response to mocked service and same object is being updated and saved in database, you need to validate values in that object.

 assertFalse(account.getRoles().contains(Role.ROLE_STAFF)); //or vice-verse

CodePudding user response:

It seems to me that [ArgumentCaptor][1] is what you need. Try the following:

@Mock
AccountRepository accountRepository;

@InjectMocks
AccountService accountService;

@Test
public void remove_staff_updates_roles() {

    Account account = new Account("username", "pass");

    when(accountRepository.findByUsername(any(String.class))).thenReturn(Optional.of(account));

    accountService.updateStaffStatusByUsername("user", false);

    ArgumentCaptor<Account> accountCaptor = ArgumentCaptor.forClass(Account.class);
    verify(accountRepository).save(accountCaptor.capture());
    assertFalse(accountCaptor.getValue().getRoles().contains(Role.ROLE_STAFF));
}
  • Related