In my entities I have some hibernate annotations for validation, like @NotEmpty, @Pattern.. and others
In my controller, on save action, it has an @Valid parameter.
But if any entity has any required field, and there is no annotation I will have problems.
So I would like to test each entity, to ensure they have the necessary notes.
Something like:
@Test(expect=IllegalArgumentException.class)
public void testAllNull() {
Person p = new Persson(); // Person name has an @NotEmpty
validator.validate(p);
}
But how to validate it? Who is called to check @Valid?
Thanks.
Here is a Spring v4.1.x based example of a test validating presence and processing of the @Valid annotation and building of custom JSON response in case of an error.
jUnit
import com.fasterxml.jackson.core.type.TypeReference;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import javax.inject.Inject;
import java.util.List;
import static org.abtechbit.miscboard.util.JsonUtils.toJson;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {
RegistrationValidationTest.MockDependencies.class,
})
public class RegistrationValidationTest {
@Inject
MockMvc mvc;
@Test
public void validatesRegistration() throws Exception {
Registration registration = ... //build an invalid Registration object
MvcResult result = mvc.perform(post(RegistrationController.CONTEXT_REGISTER).
contentType(MediaType.APPLICATION_JSON).
content(toJson(registration))).
andExpect(status().isBadRequest()).
andExpect(content().contentType(MediaType.APPLICATION_JSON)).
andReturn();
assertThat(result.getResolvedException(), is(notNullValue()));
String content = result.getResponse().getContentAsString();
assertThat(content, is(notNullValue()));
List<Message> messages = JsonUtils.fromJson(content, new TypeReference<List<Message>>() {
});
assertThat(messages.size(), is(1));
}
public static class MockDependencies {
@Bean
public MockMvc mvc() {
return MockMvcBuilders.standaloneSetup(new RegistrationController()).build();
}
}
}
Controller
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
import java.util.stream.Collectors;
@Controller
public class RegistrationController
{
public static final String CONTEXT_REGISTER = "/register";
@RequestMapping(value = CONTEXT_REGISTER, method = RequestMethod.POST)
@ResponseBody
public String register(@RequestBody @Valid Registration registration) {
//perform registration
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<List> handleValidationException(MethodArgumentNotValidException ex) {
//Build a list of custom Message{String message;} objects
List<Message> messages = ex.getBindingResult().getAllErrors().
stream().map(e->new Message(e.getDefaultMessage())).collect(Collectors.toList());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).contentType(MediaType.APPLICATION_JSON).body(messages);
}
}