【问题标题】:Test @Valid annotation with SpringMVC Maven使用 SpringMVC Maven 测试 @Valid 注解
【发布时间】:2017-12-12 14:04:04
【问题描述】:

我正在研究 Spring in Action 4 一书的第 5 章示例。当我运行测试类时,我发现其中一个 @Valid 测试不起作用,看起来好像从未发生过验证(返回状态代码302 并且视图的名称是“/spitter/null”)。但是,当我在 Tomcat 中运行它时,它运行良好。

验证 jars(hibernate-validator 及其依赖项)使用 Maven 加载。

整个项目在github

有什么想法吗?

测试代码sn-p:

@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 sn-p:

  @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 sn-p:

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

非常感谢!

【问题讨论】:

  • 是否需要使用standaloneSetup?您是否考虑过 webAppContextSetup?
  • 我刚刚尝试了 webAppContextSetup,它抛出了 org.springframework.dao.DataIntegrityViolationException,因为列用户名不允许插入 null。尽管如此,@Valid 验证并没有发生。如果经过验证,则不应抛出异常。

标签: spring unit-testing spring-mvc bean-validation jsr


【解决方案1】:

我尝试了post 的最佳答案,它奏效了。我在 pom.xml 中将 hibernate-validator 版本从 5.4.1.final 更改为 5.2.4.finalgithub 项目也已更新。

【讨论】:

    【解决方案2】:

    我克隆了您的存储库,并且能够通过将您的 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.E​​xpressionFactory'。检查您是否具有 EL 依赖项 在类路径上,或使用 ParameterMessageInterpolator 代替

    我注意到您更新了您的 shouldFailValidationWithNoData 测试以使用 webAppContextSetup 但仍然没有必要调用 mock(SpitterRepository.class)

    【讨论】:

    • 感谢 webAppContextSetup 的建议。我尝试更新 jsp-api,但它在我的机器上不起作用,但您描述的异常的另一种解决方案(stackoverflow.com/questions/24386771/…)解决了我的问题。我在 pom 中将 hibernate-validator 版本从 5.4.1.final 更改为 5.2.4.final
    【解决方案3】:

    @Validated标记你的SpitterController

    import org.springframework.validation.annotation.Validated;
    
    @Controller
    @Validated
    @RequestMapping("/spitter")
    public class SpitterController {
    

    @Autowired SpitterController 并创建 MethodValidationPostProcessor bean,该 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 {
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2023-03-26
      • 2017-10-25
      • 1970-01-01
      • 2012-08-10
      • 1970-01-01
      • 2013-07-04
      • 2014-05-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多