Create RegistrationManagementTests

Now, we know what RegistrationManagement does and we have the User entity ready, so let's create the RegistrationManagementTests unit test. We will focus on the following:

  • Make sure registering a user with an existing username fails
  • Make sure registering a user with an existing email address fails
  • Make sure registering a user with valid data succeeds and the password is encrypted
  • Make sure all users' email addresses are saved as lowercase in the repository

The following are the test methods we will create to cover the cases listed previously:

  • register_existedUsername_shouldFail()
  • register_existedEmailAddress_shouldFail()
  • register_uppercaseEmailAddress_shouldSucceedAndBecomeLowercase()
  • register_newUser_shouldSucceed()

Here is how the first test method in the RegistrationManagementTests class looks:

...
public class RegistrationServiceTests {
...
@Test(expected = UsernameExistsException.class)
public void register_existedUsername_shouldFail() throws RegistrationException {
String username = "existUsername";
String emailAddress = "[email protected]";
String password = "MyPassword!";
// We just return an empty user object to indicate an existing user
when(repositoryMock.findByUsername(username)).thenReturn(new User());
instance.register(username, emailAddress, password);
}
}

The same as UserServiceImplTests, in this test we also need to create mocks and instantiate the RegistrationManagement instance inside the setUp() method. 

As you can see, in this test method, we define the behavior of repositoryMock to return a user as the result of the findByUsername() method. With this setup, we expect RegistrationManagement to throw UsernameExistsException. If this exception is not thrown, then the implementation of RegistrationManagement is incorrect.

The register_existedEmailAddress_shouldFail() method is similar to the first method and we will not list it here. The only difference is that we define the mock's behavior for the findByEmailAddress() method and expect EmailAddressExistsException to be thrown.

Here is how the third method looks:

@Test
public void register_uppercaseEmailAddress_shouldSucceedAndBecomeLowercase()
throws RegistrationException {
String username = "sunny";
String emailAddress = "[email protected]";
String password = "MyPassword!";
instance.register(username, emailAddress, password);
User userToSave = User.create(username, emailAddress.toLowerCase(), password);
verify(repositoryMock).save(userToSave);
}

As you can see, in this test method we call the register() method with a mixed-case email address, and we expect the register() method to make sure that repository saves the user and the email address is in lowercase.

Here is how the last test method looks:

@Test
public void register_newUser_shouldSucceed() throws RegistrationException {
String username = "sunny";
String emailAddress = "[email protected]";
String password = "MyPassword!";
String encryptedPassword = "EncryptedPassword";
User newUser = User.create(username, emailAddress, encryptedPassword);

// Setup repository mock
// Return null to indicate no user exists
when(repositoryMock.findByUsername(username)).thenReturn(null);
when(repositoryMock.findByEmailAddress(emailAddress)).thenReturn(null);
doNothing().when(repositoryMock).save(newUser);
// Setup passwordEncryptor mock
when(passwordEncryptorMock.encrypt(password))
.thenReturn("EncryptedPassword");

User savedUser = instance.register(username, emailAddress, password);
InOrder inOrder = inOrder(repositoryMock);
inOrder.verify(repositoryMock).findByUsername(username);
inOrder.verify(repositoryMock).findByEmailAddress(emailAddress);
inOrder.verify(repositoryMock).save(newUser);
verify(passwordEncryptorMock).encrypt(password);
assertEquals("Saved user's password should be encrypted",
encryptedPassword, savedUser.getPassword());
}

As you can see, at the beginning of this test method, we prepare all of the test data. Then, we define the behavior of the mocks. As a matter of fact, we don't have to define the behavior of repositoryMock here, because by default the behavior of its findByUsername() method, the findByEmailAddress() method is returned null, and its save() method does nothing. We add those behavior definitions here to make that explicit, which will make our test stronger. The encrypt() method of passwordEncryptorMock will return the encrypted password we specified.

In this test, we use Mockito's InOrder API to verify that the invocations of the methods of repositoryMock occurred in a specific order. Then, we verify that the encrypt() method of passwordEncryptor has been invoked, and the password stored in the saved user is the encrypted version, not the plain text version.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.227.111.208