I learning Spring Boot web application with .jsp, and I'm struggling a lot with the testing concepts. From the SO and YT guides I implemented the Mockito thing, but honestly I do not clearly undesrtand how does it work.
I have a Registration form with 4 fields for name, lastname, email and password. This POST request is handled by the registerAction method in RegisterController. In this method I have two self-written validators for email and password. The tests should handle the cases when User data are given properly and if the errors are sent when inputs are not correct.
I tried to write tests for the controller but I'm constantly getting an exception NullPointerExpection. Looking into the debugger, the User object sent from the testing class has null attributes, which probably is the reason the exceptions.
Testing class:
@SpringBootTest
@AutoConfigureMockMvc
class RegisterControllerTest {
@Autowired
private WebApplicationContext wac;
@MockBean
private UserService userService;
@Autowired
private Gson gson;
@Autowired
private MockMvc mockMvc;
@BeforeEach
void setUp() {
initMocks(this);
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac)
.apply(springSecurity()).build();
}
@Test
void show_register_action() throws Exception {
User user = prepareUserEmpty();
this.mockMvc.perform(post("/adduser")
.contentType(MediaType.APPLICATION_JSON)
.content(gson.toJson(user)))
.andDo(print())
.andExpect(status().isOk());
}
private User prepareUserEmpty(){
User user = new User();
user.setEmail("");
user.setPassword("");
user.setName("");
user.setLastName("");
return user;
}
}
RegisterController:
@Controller public class RegisterController {
@Autowired
private UserService userService;
@Autowired
private EmailSender emailSender;
@Autowired
MessageSource messageSource; // Allows to obtain messages from message.properties to Java code
@POST
@RequestMapping(value = "/adduser")
public String registerAction(User user, BindingResult result, Model model, Locale locale){ // BindingResult for validation, Locale for messageSource
String returnPage = "register";
User userExist = userService.findUserByEmail(user.getEmail());
new UserRegisterValidator().validate(user, result);
new UserRegisterValidator().validateEmailExist(userExist, result);
if (!(result.hasErrors())){
userService.saveUser(user);
model.addAttribute("message", messageSource.getMessage("user.register.success.email", null, locale));
returnPage = "index";
}
return returnPage;
} }
Validators:
public class UserRegisterValidator implements Validator {
@Override
public boolean supports(Class <?> cls){
return User.class.equals(cls);
}
@Override
public void validate(Object obj, Errors errors){
User u = (User) obj;
ValidationUtils.rejectIfEmpty(errors, "name", "error.userName.empty");
ValidationUtils.rejectIfEmpty(errors, "lastName", "error.userLastName.empty");
ValidationUtils.rejectIfEmpty(errors, "email", "error.userEmail.empty");
ValidationUtils.rejectIfEmpty(errors, "password", "error.userPassword.empty");
if (!u.getEmail().equals(null)){
boolean isMatch = AppdemoUtils.checkEmailOrPassword(AppdemoConstants.EMAIL_PATTERN, u.getEmail());
if (!isMatch)
errors.rejectValue("email", "error.userEmailIsNotMatch");
}
if (!u.getPassword().equals(null)){
boolean isMatch = AppdemoUtils.checkEmailOrPassword(AppdemoConstants.PASSWORD_PATTERN, u.getPassword());
if (!isMatch)
errors.rejectValue("password", "error.userPasswordIsNotMatch");
}
}
public void validateEmailExist(User user, Errors errors){
if (user != null)
errors.rejectValue("email", "error.userEmailExist");
}
}