使用自动连接依赖项进行测试,例如Validator中的会话

时间:2014-01-04 01:25:20

标签: spring-mvc mockito junit4 bean-validation

我在对象的字段上定义了很少的自定义注释,如:

public class Person{
     @Accountname 
     String email;
}

@Accountname的实现类:

       @Autowired ValidationService service;    
       @Autowired ClientSession clientSession;

    @Override
    public boolean isValid(final String email, final ConstraintValidatorContext ctx) {

                    if(!service.isAccountValid(email, clientSession)){
                    return false;
                }
            }

我正在尝试为这些注释编写junits。

    @Test
    public void validEmailTest()
    {
        person.setEmail("abc@xyz.com");

        Set<ConstraintViolation<Person>> violations = validatorInstance.getValidator().validateProperty(person, "email");
        Assert.assertEquals(1, violations.size());
    }

但是当我执行测试时它抛出了这个错误:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.clientSession': Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:343)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:34)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.getTarget(CglibAopProxy.java:663)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:614)
    at org.hibernate.validator.internal.engine.ConstraintTree.validateSingleConstraint(ConstraintTree.java:308)
    ... 45 more
Caused by: java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
    at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)
    at org.springframework.web.context.request.SessionScope.get(SessionScope.java:90)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:329)
    ... 54 more

如果验证器类依赖于会话等服务,那么如何编写junits呢?

1 个答案:

答案 0 :(得分:1)

这应该单独测试(单位)。

验证的真实逻辑在你的ValidationService中,所以在那里测试它,在AccountnameValidator中只测试那里的逻辑,注入依赖项:

@Mock ValidationService service;    
@Mock ClientSession clientSession;
@InjectMocks AccountnameValidator av = new AccountnameValidator()
//initialize mocks

//example test
when(service.isAccountValid(email, clientSession)).thenReturn(true);
boolean result = av.isValid(email, ctx);
assertTrue(result);

最后,如果您愿意,可以使用反射在电子邮件字段中验证Person类中注释的存在。