Протестируйте аннотацию @Valid с помощью SpringMVC Maven

Я работаю над примером из главы 5 книги Spring in Action 4. Когда я запускаю тестовые классы, я обнаружил, что один из тестов @Valid не работает, похоже, что проверка никогда не выполнялась (возвращенный код состояния 302 и имя представления "/spitter/null"). Однако он отлично работает, когда я запускаю его в Tomcat.

Банки проверки (hibernate-validator и его зависимости) загружаются с помощью Maven.

Весь проект находится на github.

Любые идеи?

фрагмент тестового кода:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes={RootConfig.class, WebConfig.class})
public class SpitterControllerTest {
    @Test
    public void shouldFailValidationWithNoData() throws Exception {
        SpitterRepository mockRepository = mock(SpitterRepository.class);    
        SpitterController controller = new SpitterController(mockRepository);
        MockMvc mockMvc = standaloneSetup(controller).build();

        mockMvc.perform(post("/spitter/register"))
            .andExpect(status().isOk())
            .andExpect(view().name("registerForm"))
            .andExpect(model().errorCount(5))
            .andExpect(model().attributeHasFieldErrors(
                "spitter", "firstName", "lastName", "username", "password", "email"));
    }
}

Фрагмент SpitterController:

  @RequestMapping(value="/register", method=POST)
  public String processRegistration(
      @Valid Spitter spitter, 
      Errors errors) {
    if (errors.hasErrors()) {
      return "registerForm";
    }

    spitterRepository.save(spitter);
    return "redirect:/spitter/" + spitter.getUsername();
  }

Фрагмент Спиттера:

@NotNull
  @Size(min=5, max=16)
  private String username;

  @NotNull
  @Size(min=5, max=25)
  private String password;

  @NotNull
  @Size(min=2, max=30)
  private String firstName;

  @NotNull
  @Size(min=2, max=30)
  private String lastName;

  @NotNull
  @Email
  private String email;

Большое спасибо!


person fall    schedule 08.07.2017    source источник
comment
Требуется ли использование standaloneSetup? Рассматривали ли вы вместо этого webAppContextSetup?   -  person Sean Carroll    schedule 08.07.2017
comment
Я только что попробовал webAppContextSetup, и он выдал org.springframework.dao.DataIntegrityViolationException, потому что вставка нуля не разрешена для имени пользователя столбца. Тем не менее, проверка @Valid не произошла. Если это проверено, исключение не должно было быть выброшено.   -  person fall    schedule 10.07.2017


Ответы (3)


Я клонировал ваш репозиторий и смог заставить работать проверку, обновив вашу зависимость jsp-api до 2.2.

<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.2</version>
    <scope>provided</scope>
</dependency>

Существуют более новые версии этой зависимости, на которые вы, возможно, захотите взглянуть. При использовании версии 2.1 не было зарегистрированных/добавленных валидаторов в ExtendedServletRequestDataBinder или, точнее, SpringValidatorAdapter targetValidator был нулевым.

Основная причина заключалась в том, что приведенное ниже исключение было вызвано в OptionalValidatorFactoryBean.afterPropertiesSet

javax.validation.ValidationException: HV000183: невозможно инициализировать 'javax.el.ExpressionFactory'. Убедитесь, что у вас есть зависимости EL от пути к классам, или вместо этого используйте ParameterMessageInterpolator.

Я заметил, что вы обновили свой тест shouldFailValidationWithNoData, чтобы использовать webAppContextSetup, но по-прежнему имеете вызов mock(SpitterRepository.class), который не нужен.

person Sean Carroll    schedule 10.07.2017
comment
Спасибо за совет по настройке webAppContextSetup. Я попытался обновить jsp-api, и это не сработало на моей машине, но другое решение (stackoverflow.com/questions/24386771/) к исключению, которое вы описали, решило мою проблему. Я изменил версию hibernate-validator с 5.4.1.final на 5.2.4.final в pom. - person fall; 12.07.2017

Я попробовал этот post лучший ответ и это сработало. Я изменил версию hibernate-validator с 5.4.1.final на 5.2.4.final в pom. Также обновлен проект github.

person fall    schedule 12.07.2017

Отметьте свой SpitterController с помощью @Validated

import org.springframework.validation.annotation.Validated;

@Controller
@Validated
@RequestMapping("/spitter")
public class SpitterController {

@Autowired SpitterController и создайте MethodValidationPostProcessor bean-компонент, который делегирует поставщику JSR-303 выполнение проверки аннотированных методов на уровне метода следующим образом:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = { RootConfig.class, WebConfig.class,
        SpitterControllerTest.Config.class })
public class SpitterControllerTest {

    @Autowired
    private SpitterController spitterController;

    @Configuration
    public static class Config {
        @Bean
        public MethodValidationPostProcessor methodValidationPostProcessor() {
            return new MethodValidationPostProcessor();
        }
    }

    @Test
    public void shouldFailValidationWithNoData() throws Exception {
    }

}
person Arpit Aggarwal    schedule 08.07.2017