问题 单元测试的良好模式形成了在Spring MVC中具有基于注释的验证的bean


对表单bean使用基于注释的验证时,为了确保为每个字段指定正确的验证注释,对这些bean进行单元测试的最佳做法是什么?

例如,如果您有:

public class MyForm {
    @NotNull
    private String name;
}

验证这一点的最佳方法是什么? @NotNull 适用于它吗?

一个显而易见的方法是创建一个验证器,在它上面抛出一个null并期望它失败。但在我看来,这不是最好的方法,因为你将测试行为和实现 @NotNull 使用它而不是信任框架。

理想情况下,我想使用反射或实用程序,这使我有可能只是声明一个 @NotNull (和任何其他)验证应用于给定字段,而不必发送未通过验证的各种值组合。

是否有一种优雅的方式来做到这一点,或者我是否在正确的轨道上?


5797
2018-03-01 12:17


起源



答案:


您还可以使用验证工厂为您的Beans编写单元测试,这些测试使用JSR303进行注释。 见例子: http://musingsofaprogrammingaddict.blogspot.com/2009/02/using-bean-validation-with-spring.html


4
2018-03-01 13:02



谢谢。帖子中的主要文章实际上就是我想要避免的方式。然而,该帖子(来自gunnar)的评论是按照我希望的方式进行的 - 检查注释而不是注释的行为。 - Ashkan Aryan
请加链接的文章mandantory部分为你的答案,以防止信息丢失,如果页面下线的一部分。 - CSchulz


答案:


您还可以使用验证工厂为您的Beans编写单元测试,这些测试使用JSR303进行注释。 见例子: http://musingsofaprogrammingaddict.blogspot.com/2009/02/using-bean-validation-with-spring.html


4
2018-03-01 13:02



谢谢。帖子中的主要文章实际上就是我想要避免的方式。然而,该帖子(来自gunnar)的评论是按照我希望的方式进行的 - 检查注释而不是注释的行为。 - Ashkan Aryan
请加链接的文章mandantory部分为你的答案,以防止信息丢失,如果页面下线的一部分。 - CSchulz


你应该考虑两件事:

不要测试您的第三方库/框架。

你应该依赖它们,它们应该已经由他们的维护者和周围的社区用户进行测试。你宁愿测试它们 评估 他们。确保它们符合您的需求并降低风险。

测试行为真的很重要!

在绝大多数应用程序中,没有什么地方可以实现 单元 测试,因为业务逻辑很小,在应用程序的多个模块中很普遍。因此,您应该考虑集成测试,其优先级高于单元测试。通过使用行为方法可以更容易地捕获这一点。

所以,要回答你的问题,你不应该尝试单独测试表单bean。它只是一个运输对象。您应该测试的是接收器如何对该形式做出反应,并检查正常情况和边缘情况。


5
2018-03-01 12:56



我同意不测试第三方库,但测试您的配置与测试行为一样重要。 - frant.hartm
是的,这是一个好点,我同意这一点。不过,我认为(作为frant.hartm说的),有房,以测试配置。其他一切(即实际验证)与bean无直接关系,不应在此进行测试。 - Ashkan Aryan
'所以你应该考虑集成测试的优先级高于单元测试。' - artbristol


你可以轻松测试它。

假设您正在使用Hibernate Validator。 或多或少,它应该是这样的

    import javax.validation.ConstraintViolation;
    import junit.framework.Assert;
    import org.hibernate.validator.HibernateValidator;
    import org.junit.Before;
    import org.junit.Test;
    import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;

 private LocalValidatorFactoryBean localValidatorFactory;


@Before
public void setup() {
    localValidatorFactory = new LocalValidatorFactoryBean();
    localValidatorFactory.setProviderClass(HibernateValidator.class);
    localValidatorFactory.afterPropertiesSet();
}

  @Test
  public void testNullValidationError() {
        final MyForm myForm= new MyForm ();
        myForm.setName(null);
        Set<ConstraintViolation<MyForm >> constraintViolations =      localValidatorFactory.validate(myForm);
        Assert.assertTrue("Your error message", constraintViolations.notNull == null);
    }

3
2018-03-01 13:40



不,这是我到底要避免Bean的单元测试,如在原来的职位说明,并按照UPS。 - Ashkan Aryan


我们测试bean属性的注释,作为表示层和spring容器之间集成测试的一部分。

我们做的是创建假的MockPortletContext,DispatcherPortlet和MockRequests(这些类是spring-test库的一部分), 填写请求,使它们看起来像真实的表单被提交,然后调用dispatcherPortlet。 (我们有portlet环境,但没关系)

然后你可以检查你的后端被approprietly调用,或者响应包含绑定结果与预期的验证错误,这是你需要的..


2
2018-03-01 13:25