I am trying to substitute the correct use of Mockito, during a test session by JUnit, in place of to stub a class. Unfortunately on web there are a lot of tutorials regarding Mockito but, less for the stub approach, and I would like to learn this technique.
This test is made by Mockito:
@Test
public void addWrongNewUserSpaceInUsername() throws Exception {
when(userValidator.isValidUsername(user.getUsername())).thenReturn(false);
try {
mockMvc.perform(
post("/register")
.contentType(MediaType.APPLICATION_JSON)
.content(asJsonString(user)
));
} catch (Exception e) {
Assert.assertTrue(e.getCause() instanceof UsernameNotValidException);
}
}
To clarify these are the classes involved:
1) Controller
@RestController
public class UserController {
@Autowired
RepositoryUserDB repositoryUserDB;
@Autowired
UserValidator userValidator;
@RequestMapping(value = "/register", method = RequestMethod.POST)
public User createUser(@RequestBody User user) {
if (userValidator.isValidUsername(user.getUsername())) {
if(!userValidator.isValidPassword(user.getPassword())){
throw new PasswordNotValidException();
}
if(userValidator.isValidDateOfBirth(user.getDateOfBirth()) == false){
throw new DOBNotValidException();
}
// se lo user e' gia' presente
if (repositoryUserDB.getUserByUsername(user.getUsername()) == null) {
return repositoryUserDB.createUser(user);
}
throw new UsernameAlreadyExistException();
} else throw new UsernameNotValidException();
}
}
2)Interface of repo:
public interface RepositoryUserDB {
User getUserByUsername(String username);
User createUser(User user);
}
3)Repo:
@Component
public class MemoryUserDB implements RepositoryUserDB{
Map<String, User> repo;
public MemoryUserDB() {
this.repo = new HashMap<>();
}
@Override
public User getUserByUsername(String username) {
return repo.get(username);
}
@Override
public User createUser(User user) {
repo.put(user.getUsername(),user);
return repo.get(user.getUsername());
}
}
4) Validator:
@Component
public class UserValidator {
public boolean isValidUsername(String username) {
return username.matches("^[a-zA-Z0-9]+$");
}
public boolean isValidPassword(String pwd) {
if (pwd == null)
return false;
return pwd.matches("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d){4,}.+$");
}
public boolean isValidDateOfBirth(String DOB) {
return DOB.matches("^(?:(?:(?:0?[13578]|1[02])(\\/|-|\\.)31)\\1|(?:(?:0?[1,3-9]|1[0-2])(\\/|-|\\.)(?:29|30)\\2))(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$|^(?:0?2(\\/|-|\\.)29\\3(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))(\\/|-|\\.)(?:0?[1-9]|1\\d|2[0-8])\\4(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$");
}
}
5)ResEntityExceptionHandler
@ControllerAdvice
public class RestEntityExceptionHandler {
@ExceptionHandler(UsernameNotValidException.class)
@ResponseStatus(value = HttpStatus.FORBIDDEN, reason = "username wrong")
public void handleUsernameException() {
}
@ExceptionHandler(UsernameAlreadyExistException.class)
@ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = "the username is already presents")
public void handleUsername() {
}
@ExceptionHandler(PasswordNotValidException.class)
@ResponseStatus(value = HttpStatus.FORBIDDEN, reason = "password wrong")
public void handlePasswordException() {
}
@ExceptionHandler(DOBNotValidException.class)
@ResponseStatus(value = HttpStatus.FORBIDDEN, reason = "Date Of Birth wrong")
public void handleDOBException(){
}
}