Question

I have few custom annotations defined on fields of an object like:

public class Person{
     @Accountname 
     String email;
}

Implementation class of @Accountname:

       @Autowired ValidationService service;    
       @Autowired ClientSession clientSession;

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

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

I am trying to write junits for these annotations.

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

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

But its throwing this error when I execute the test:

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

Any idea on how to write junits if a validator class has a dependency on services like session etc.?

Was it helpful?

Solution

This should be tested separately (units).

The real logic that validates is in your ValidationService, so test it there, in AccountnameValidator test only the logic that is in there, injecting your dependencies:

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

And finally if you want you can validate presence of the annotation in Person class on email field using reflection.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top