Integration testing fails while testing @NotNull

I cloned this project and modified Hotel.java as:

@Entity public class Hotel implements Serializable { . . @javax.validation.constraints.NotNull //@Column(nullable = false) private String address; . . } 

When creating a mail request, for example:

 curl -H "Content-Type: application/json" -X POST -d '{}' http://localhost:8080/api/hotels 

answer:

 { "timestamp": 1479213670718, "status": 500, "error": "Internal Server Error", "exception": "javax.validation.ConstraintViolationException", "message": "org.springframework.web.util.NestedServletException: Request processing failed; nested exception is javax.validation.ConstraintViolationException: Validation failed for classes [sample.data.rest.domain.Hotel] during persist time for groups [javax.validation.groups.Default, ]\nList of constraint violations:[\n\tConstraintViolationImpl{interpolatedMessage='may not be null', propertyPath=address, rootBeanClass=class sample.data.rest.domain.Hotel, messageTemplate='{javax.validation.constraints.NotNull.message}'}\n]", "path": "/api/hotels" } 

Then I wrote a test for this case:

 @RunWith(SpringRunner.class) @SpringBootTest @ActiveProfiles("scratch") public class SampleDataRestApplicationTests { . . @Test public void createHotel_andExpectServerError() throws Exception { this.mvc.perform(post("/api/hotels").content("{}")) .andExpect(status().is5xxServerError()); } } 

When I run the test, it throws this error:

 org.springframework.web.util.NestedServletException: Request processing failed; nested exception is javax.validation.ConstraintViolationException: Validation failed for classes [sample.data.rest.domain.Hotel] during persist time for groups [javax.validation.groups.Default, ] List of constraint violations:[ ConstraintViolationImpl{ interpolatedMessage='may not be null', propertyPath=address, rootBeanClass=class sample.data.rest.domain.Hotel, messageTemplate='{javax.validation.constraints.NotNull.message}'} ] 

and therefore he fails, but I expect him to pass instead.

It seems that by default, the Handler exception that handles the ConstraintViolationException is usually not available in tests.

Thanks.

+5
source share
1 answer

I cannot reproduce your result, but it may be possible to get closer to your problem by clarifying some things.

If I run your curl command (with the optional -v flag to get headers) on my machine, I get a client error, or rather 409 Conflict .

 curl -v -H "Content-Type: application/json" -X POST -d '{}' http://localhost:8080/api/hotels Note: Unnecessary use of -X or --request, POST is already inferred. * Trying 127.0.0.1... * Connected to localhost (127.0.0.1) port 8080 (#0) > POST /api/hotels HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/7.47.0 > Accept: */* > Content-Type: application/json > Content-Length: 2 > * upload completely sent off: 2 out of 2 bytes < HTTP/1.1 409 Conflict < Date: Sun, 22 Jan 2017 12:29:45 GMT < Content-Type: application/hal+json;charset=UTF-8 < Transfer-Encoding: chunked < * Connection #0 to host localhost left intact {"cause":{"cause":{"cause":null,"message":"NULL not allowed for column \"ADDRESS\"; SQL statement:\ninsert into hotel (id, address, city_id, name, zip) values (null, ?, ?, ?, ?) [23502-193]"},"message":"could not execute statement"},"message":"could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement"} 

The same thing happens when you run your test in my IDE (STS):

 java.lang.AssertionError: Range for response status value 409 expected:<SERVER_ERROR> but was:<CLIENT_ERROR> at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:54) at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:81) at org.springframework.test.web.servlet.result.StatusResultMatchers$7.match(StatusResultMatchers.java:132) at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:171) ... 

So, at first there is no difference between the tests and the running application, DataIntegrityViolationException / ConstraintViolationException is displayed in both cases at 409.

If this is correct, this is another question, but maybe sending the wrong / invalid data is actually a client error.

If you still want to change this, you should add your own ExceptionHandler, perhaps this way:

 import org.hibernate.exception.ConstraintViolationException; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.context.request.WebRequest; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; @RestControllerAdvice public class ConstraintViolationExceptionHandler extends ResponseEntityExceptionHandler { @ExceptionHandler({ ConstraintViolationException.class }) public ResponseEntity<Object> handleConstraintViolationException(Exception ex, WebRequest request) { return handleExceptionInternal(ex, "I think it the servers fault!", new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR, request); } } 

Perhaps this can solve your problem accordingly. give you a hint. Or is there another question that I have not received?

0
source

Source: https://habr.com/ru/post/1259766/


All Articles