Тестирование @Validated RestController в автономном MockMvc не работает

У меня есть RestController с аннотацией @Validated для проверки переменных пути/параметров запроса:

@RestController
@Validated
public class MainController implements ApplicationListener<ApplicationReadyEvent> {

    @Autowired
    private CarsService carsService;

    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public void handleException(ConstraintViolationException ex) {}

    @GetMapping(
            value = "/",
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> getCars(
            @RequestParam(value = "offset", defaultValue = "0") @PositiveOrZero
                    Integer offset,
            @RequestParam(value = "limit", defaultValue = paginationLimitDefault)
            @Positive @Max(paginationLimitMax)
                    Integer limit) {
        ...
        ...
        Map responseBody = new HashMap<String, Object>();
        responseBody.put("offset", offset);
        responseBody.put("limit", limit);
        return ResponseEntity.status(HttpStatus.OK).body(responseBody);
    }
}

Теперь я хочу протестировать уровень контроллера с помощью автономного mockMvc:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@ActiveProfiles("test")
public class TestMainController {

    @InjectMocks
    private MainController mainController;

    @Mock
    private CarsService carsServiceMock;

    private MockMvc mockMvc;

    @Before
    public void initMocks() {
        MockitoAnnotations.initMocks(this);
        mockMvc = MockMvcBuilders.standaloneSetup(mainController).build();
    }

    @Test
    public void getCarsInvalidOffset() throws Exception {
        mockMvc.perform(get("/")
                .param("offset", "-1"))
                .andExpect(status().isBadRequest());
    }

    @Test
    public void getCarsInvalidLimit() throws Exception {
        mockMvc.perform(get("/")
                .param("limit", "0"))
                .andExpect(status().isBadRequest());
        mockMvc.perform(get("/")
                .param("limit", "-1"))
                .andExpect(status().isBadRequest());
        mockMvc.perform(get("/")
                .param("limit", "101"))
                .andExpect(status().isBadRequest());
    }
}   

Проблема в том, что тесты с недопустимыми параметрами (оба теста в приведенном выше фрагменте кода) должны были возвращать неверный запрос, фактически возвращая 200 OK, и в результате тест терпит неудачу.
Как я могу это исправить? Спасибо.


person Yosi Karl    schedule 13.03.2019    source источник
comment
Работает ли ваша проверка вне тестовой среды?   -  person cgcgbcbc    schedule 13.03.2019
comment
да, это работает.   -  person Yosi Karl    schedule 13.03.2019
comment
Зачем запускать Spring Boot Test для этого? По памяти вы можете либо использовать WebMvcTest, либо автоматически подключить MockMvc, и это сработает, если вам нужно настроить автономную установку, чтобы иметь валидатор.   -  person Darren Forsythe    schedule 13.03.2019
comment
Я тоже пробовал с WebMvcTest, не получилось.   -  person Yosi Karl    schedule 13.03.2019
comment
Возможный дубликат stackoverflow .com/questions/24049480/   -  person amseager    schedule 13.03.2019
comment
Определенно дубликат stackoverflow.com/questions/49160611/. Обходной путь: используйте MockMvcBuilders.webAppContextSetup() или @WebMvcTest.   -  person Hein Blöd    schedule 16.02.2021


Ответы (2)


Я подозреваю, что из-за того, что вы издеваетесь над MainController, @Validated не вступает в силу. Попробуй это:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@ActiveProfiles("test")
public class TestMainController {

    @Autowired
    private MainController mainController;

    @MockBean
    private CarsService carsServiceMock;

    @Autowired
    private WebApplicationContext context;

    private MockMvc mockMvc;

    @Before
    public void initMocks() {
        mockMvc = MockMvcBuilders.webAppContextSetup(context)
        .build();
    } 
person voliveira89    schedule 13.03.2019
comment
Это не отдельная установка. - person Mene; 01.09.2020

Это невозможно с standaloneSetup.

Для получения дополнительной информации см.: Как включить проверку параметров контроллера для автономного MockMvc.

Для тестового примера @Validated нам нужно:

MockMvcBuilders.webAppContextSetup() 
person Awadesh    schedule 01.07.2021