Printemps de service de l'unité de test à l'aide d'mockito

Jusqu'à présent, les réponses de SORTE a été totalement satisfaisant pour mes problèmes. Je suis en train d'apprendre les tests unitaires avec Junit et Mockito et je veux tester ma classe de service qui est une partie de mon Ressort de l'application web. J'ai lu de nombreux tutoriels et articles et j'ai toujours des problèmes pour rédiger les tests unitaires pour ma couche de service. Je voudrais savoir des réponses à mes questions, mais d'abord je colle le code:

Classe de Service

public class AccountServiceImpl implements AccountService {

@Autowired
AccountDao accountDao, RoleDao roleDao, PasswordEncoder passwordEncoder, SaltSource saltSource;

@PersistenceContext
EntityManager entityManager;

public Boolean registerNewAccount(Account newAccount) {
    entityManager.persist(newAccount);
    newAccount.setPassword(passwordEncoder.encodePassword(newAccount.getPassword(), saltSource.getSalt(newAccount)));
    setRoleToAccount("ROLE_REGISTERED", newAccount);

    return checkIfUsernameExists(newAccount.getUsername());    
}

public void setRoleToAccount(String roleName, Account account) {
    List<Role> roles = new ArrayList<Role>();
    try {
        roles.add(roleDao.findRole(roleName));
    } catch(RoleNotFoundException rnf) {
        logger.error(rnf.getMessage());
    }
    account.setRoles(roles);
}

public Boolean checkIfUsernameExists(String username) {
    try {
        loadUserByUsername(username);
    } catch(UsernameNotFoundException unf) {
        return false;
    }
    return true;
}

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {  
    try {
        Account loadedAccount = accountDao.findUsername(username);
        return loadedAccount;   
    } catch (UserNotFoundException e) {
        throw new UsernameNotFoundException("User: " + username + "not found!");
    }
}
}

Mon inachevé de la classe de test

@RunWith(MockitoJUnitRunner.class)
public class AccountServiceImplTest {

private AccountServiceImpl accountServiceImpl;
@Mock private Account newAccount;
@Mock private PasswordEncoder passwordEncoder;
@Mock private SaltSource saltSource;
@Mock private EntityManager entityManager;
@Mock private AccountDao accountDao;
@Mock private RoleDao roleDao;

@Before
public void init() {
    MockitoAnnotations.initMocks(this);
    accountServiceImpl = new AccountServiceImpl();
    ReflectionTestUtils.setField(accountServiceImpl, "entityManager", entityManager);
    ReflectionTestUtils.setField(accountServiceImpl, "passwordEncoder", passwordEncoder);
    ReflectionTestUtils.setField(accountServiceImpl, "saltSource", saltSource);
    ReflectionTestUtils.setField(accountServiceImpl, "accountDao", accountDao);
    ReflectionTestUtils.setField(accountServiceImpl, "roleDao", roleDao);
}

@Test
public void testRegisterNewAccount() {
    Boolean isAccountCreatedSuccessfully = accountServiceImpl.registerNewAccount(newAccount);

    verify(entityManager).persist(newAccount);
    verify(newAccount).setPassword(passwordEncoder.encodePassword(newAccount.getPassword(), saltSource.getSalt(newAccount)));
    assertTrue(isAccountCreatedSuccessfully);
}

@Test
public void testShouldSetRoleToAccount() throws RoleNotFoundException{
    Role role = new Role(); //Maybe I can use mock here?
    role.setName("ROLE_REGISTERED");
    when(roleDao.findRole("ROLE_REGISTERED")).thenReturn(role);
    accountServiceImpl.setRoleToAccount("ROLE_REGISTERED", newAccount);
    assertTrue(newAccount.getRoles().contains(role)); 
}

}

Questions:

  1. Quel est le meilleur moyen de faire des tests unitaires où j'ai méthodes en méthodes comme dans ma classe de service? Puis-je les tester séparément, comme ci-dessus? [J'ai divisé mon code en quelques méthodes pour avoir plus propre code]
  2. Est testRegisterNewAccount() bon test unitaire pour ma méthode de service? Test est vert mais je ne suis pas sûr à ce sujet.
  3. Je suis d'échec dans ma testShouldSetRoleToAccount. Ce que je fais mal?
  4. Comment tester checkIfUsernameExists?

Peut-être que quelqu'un va m'aider parce que j'ai passé une couple de jours et je n'ai pas fait un progrès 🙁


Mise à JOUR

Fini de la classe de test

@RunWith(MockitoJUnitRunner.class)
public class AccountServiceImplTest extends BaseTest {
private AccountServiceImpl accountServiceImpl;
private Role role;
private Account account;
@Mock private Account newAccount;
@Mock private PasswordEncoder passwordEncoder;
@Mock private SaltSource saltSource;
@Mock private EntityManager entityManager;
@Mock private AccountDao accountDao;
@Mock private RoleDao roleDao;
@Before
public void init() {
accountServiceImpl = new AccountServiceImpl();
role = new Role();
account = new Account();
ReflectionTestUtils.setField(accountServiceImpl, "entityManager", entityManager);
ReflectionTestUtils.setField(accountServiceImpl, "passwordEncoder", passwordEncoder);
ReflectionTestUtils.setField(accountServiceImpl, "saltSource", saltSource);
ReflectionTestUtils.setField(accountServiceImpl, "accountDao", accountDao);
ReflectionTestUtils.setField(accountServiceImpl, "roleDao", roleDao);
}
@Test
public void testShouldRegisterNewAccount() {
Boolean isAccountCreatedSuccessfully = accountServiceImpl.registerNewAccount(newAccount);
verify(entityManager).persist(newAccount);
verify(newAccount).setPassword(passwordEncoder.encodePassword(newAccount.getPassword(), saltSource.getSalt(newAccount)));
assertTrue(isAccountCreatedSuccessfully);
}
@Test(expected = IllegalArgumentException.class)
public void testShouldNotRegisterNewAccount() {
doThrow(new IllegalArgumentException()).when(entityManager).persist(account);
accountServiceImpl.registerNewAccount(account);
}
@Test
public void testShouldSetRoleToAccount() throws RoleNotFoundException {
when(roleDao.findRole(anyString())).thenReturn(role);
accountServiceImpl.setRoleToAccount("ROLE_REGISTERED", account);
assertTrue(account.getRoles().contains(role)); 
}
@Test
public void testShouldNotSetRoleToAccount() throws RoleNotFoundException {
when(roleDao.findRole(anyString())).thenThrow(new RoleNotFoundException());
accountServiceImpl.setRoleToAccount("ROLE_RANDOM", account);
assertFalse(account.getRoles().contains(role));
}
@Test
public void testCheckIfUsernameExistsIsTrue() throws UserNotFoundException {
when(accountDao.findUsername(anyString())).thenReturn(account);
Boolean userExists = accountServiceImpl.checkIfUsernameExists(anyString());
assertTrue(userExists);
}
@Test
public void testCheckIfUsernameExistsIsFalse() throws UserNotFoundException {
when(accountDao.findUsername(anyString())).thenThrow(new UserNotFoundException());
Boolean userExists = accountServiceImpl.checkIfUsernameExists(anyString());
assertFalse(userExists);
}
@Test 
public void testShouldLoadUserByUsername() throws UserNotFoundException {
when(accountDao.findUsername(anyString())).thenReturn(account);
Account foundAccount = (Account) accountServiceImpl.loadUserByUsername(anyString());
assertEquals(account, foundAccount);
}
@Test(expected = UsernameNotFoundException.class)
public void testShouldNotLoadUserByUsername() throws UserNotFoundException {
when(accountDao.findUsername(anyString())).thenThrow(new UsernameNotFoundException(null));
accountServiceImpl.loadUserByUsername(anyString());
}
}

OriginalL'auteur Mariusz Grodek | 2012-01-23