2016-11-15 17 views
5

I sklonowany this project i zmienił Hotel.java jak:testy Integracja nie podczas testowania @NotNull

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

składając wniosek po jak:

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

odpowiedź brzmi:

{ 
    "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" 
} 

Następnie napisałem test dla tego przypadku:

@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()); 
    } 

} 

Kiedy wykonać test, zgłasza ten błąd:

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}'} 
] 

i tak to nie, ale można oczekiwać, że zamiast przechodzić.

Wygląda na to, że domyślny wyjątekHandler, który obsługuje zwykle wyjątek ConstraintViolationException, nie jest dostępny w testach.

Dzięki.

Odpowiedz

0

Nie mogę odtworzyć wyniku, ale być może uda się zbliżyć do problemu, wyjaśniając pewne rzeczy.

Jeśli wykonam polecenie curl (z dodatkową flagą -v, aby uzyskać nagłówki) na moim komputerze, pojawia się błąd klienta, aby dokładnie być 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"} 

samo dzieje wykonując test w moim 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) 
    ... 

Więc w pierwszej chwili nie ma żadnej różnicy pomiędzy testami i uruchomionej aplikacji, DataIntegrityViolationException/ConstraintViolationException jest odwzorowany w obu przypadkach the 409.

Jeśli to prawda, to kolejne pytanie, ale może wysyłanie błędnych/nieprawidłowych danych jest w rzeczywistości winą klienta.

Jeśli nadal chcesz to zmienić, trzeba dodać własną ExceptionHandler może w sposób jak poniżej:

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's the servers fault!", new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR, request); 
    } 

} 

Może to rozwiąże problem, wzgl. podpowie Ci. Czy jest jeszcze inne pytanie, którego nie dostałem?

Powiązane problemy