使用 SpringMVC Maven 测试 @Valid 注解

Test @Valid annotation with SpringMVC Maven

我正在处理本书 Spring 第 5 章的示例,在操作 4 中。当我 运行 进行测试时 类 我发现其中一个 @Valid 测试是不工作,似乎从未发生过验证(返回状态代码 302,视图名称为“/spitter/null”)。但是,当我在 Tomcat 中 运行 时它工作正常。

验证 jar(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();
  }

Spitter 片段:

@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;

非常感谢!

@Validated

标记您的 SpitterController
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 {
    }

}

我克隆了您的存储库,并且能够通过将您的 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 没有验证器registered/added,或者更准确地说,SpringValidatorAdapter targetValidator 为空。

根本原因是下面的异常在OptionalValidatorFactoryBean.afterPropertiesSet

中被抛出

javax.validation.ValidationException: HV000183: Unable to initialize 'javax.el.ExpressionFactory'. Check that you have the EL dependencies on the classpath, or use ParameterMessageInterpolator instead

我注意到您更新了 shouldFailValidationWithNoData 测试以使用 webAppContextSetup,但仍然调用了 mock(SpitterRepository.class),这不是必需的。

我试过了post's best answer and it worked. I changed the hibernate-validator version from 5.4.1.final to 5.2.4.final in pom. The github项目也更新了。