Spring Boot Test с Mockito: аннотация @Validated игнорируется во время юнит-тестов - PullRequest
0 голосов
/ 13 декабря 2018

Я использую Spring Boot 2.1.1, JUnit 5, Mockito 2.23.4.

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>2.23.4</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-junit-jupiter</artifactId>
            <version>2.23.4</version>
            <scope>test</scope>
        </dependency>

Вот мой контроллер:

@RestController
@Validated
public class AramaController {

    @ResponseStatus(value = HttpStatus.OK)
    @GetMapping("/arama")
    public List<Arama> arama(@RequestParam @NotEmpty @Size(min = 4, max = 20) String query) {
        return aramaService.arama(query);
    }
}

Этот контроллер работает должным образом.

curl без параметра «query» возвращает неверный запрос 400:

~$ curl http://localhost:8080/arama -v
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /arama HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.58.0
> Accept: */*
> 
< HTTP/1.1 400 
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Content-Length: 0
< Date: Wed, 12 Dec 2018 21:47:11 GMT
< Connection: close
< 
* Closing connection 0

curl с параметром «query = a» также возвращает неверный запрос 400:

~$ curl http://localhost:8080/arama?query=a -v
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /arama?query=a HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.58.0
> Accept: */*
> 
< HTTP/1.1 400 
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Wed, 12 Dec 2018 21:47:33 GMT
< Connection: close
< 
* Closing connection 0
{"message":"Input error","details":["size must be between 4 and 20"]}

Этот контроллер и валидация работают безупречно при работе на сервере.

Во время модульных тестов аннотация @Validated, похоже, не оказывает никакого влияния.

Вот мой тестовый код:

@ExtendWith(MockitoExtension.class)
class AramaControllerTest {

    @Mock
    private AramaService aramaService;

    @InjectMocks
    private AramaController aramaController;

    private MockMvc mockMvc;

    @BeforeEach
    private void setUp() {
        mockMvc = MockMvcBuilders
                .standaloneSetup(aramaCcontroller)
                .setControllerAdvice(new RestResponseEntityExceptionHandler())
                .build();

    }

    @Test
    void aramaValidationError() throws Exception {

        mockMvc
                .perform(
                        get("/arama").param("query", "a")
                )
                .andExpect(status().isBadRequest());

        verifyNoMoreInteractions(aramaService);
    }
}

Этот тест приводит к сбою:

java.lang.AssertionError: Status expected:<400> but was:<200>
Expected :400
Actual   :200

Поскольку аннотации @Valid проходят другие мои тесты и работают без загрузки контекста Spring, существует ли способ сделать аннотацию @Validatedработать также с Mockito (опять же, без загрузки контекста Spring)?

Ответы [ 2 ]

0 голосов
/ 15 декабря 2018

Я получил ответ в другом месте и хотел бы поделиться:

Без запуска контекста у вас не будет теста @Validator, потому что экземпляры валидатора являются бинами Spring.Тем не менее, @Valid будет работать, поскольку это стандарт JSR-303.

На данный момент я могу предложить следующее:

@SpringBootTest
@ExtendWith(SpringExtension.class)
0 голосов
/ 13 декабря 2018

возможно, вы можете попробовать использовать @WebMvcTest и добавить SpringExtension

@ExtendWith({SpringExtension.class, MockitoExtension.class})
@WebMvcTest(AramaController.class)
class AramaControllerTest {

    @Mock
    private AramaService aramaService;

    @InjectMocks
    private AramaController aramaController;

    @Autowired
    private MockMvc mockMvc;

    @Test
    void aramaValidationError() throws Exception {

        mockMvc
                .perform(
                        get("/arama").param("query", "a")
                )
                .andExpect(status().isBadRequest());

        verifyNoMoreInteractions(aramaService);
    }
}
...