Nirmalya
Nirmalya

Reputation: 205

Unit Test Custom Validator in Spring Validation

I have a custom validator as below

@Component
public class RequestValidator implements Validator {

    private SmartValidator smartValidator;

    @Autowired
    public RequestValidator(@Qualifier("smartValidator") SmartValidator smartValidator){
        this.smartValidator = smartValidator;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return RequestWrapper.class.equals(aClass);
    }

    @Override
    public void validate(Object object, Errors errors) {
        RequestWrapper requestWrapper = (RequestWrapper) object;
        if(requestWrapper.getRequest() instanceof UserRequest) {
        UserRequest userRequest = (UserRequest) requestWrapper.getRequest();
        smartValidator.validate(userRequest, errors);
    }
}

The bean for validation is as below

    public class UserRequest{

        @NotNull
        @Size(min = 1, max = 20)
        @Pattern(regexp = ValidationRegex.ALPHA_SPECIAL)
        private String firstName;

        @Size(max = 1)
        @Pattern(regexp = ValidationRegex.ALPHA)
        private String middleInitial;

        @NotNull
        @Size(min = 1, max = 20)
        @Pattern(regexp = ValidationRegex.ALPHA_SPECIAL)
        private String lastName;

        //more fields and getters and setters
}

My test class looks like this

public class UserRequestValidatorTest {

    @Mock
    SmartValidator smartValidator;

    @InjectMocks
    UserRequestValidator userRequestValidator;

    private UserRequest userRequest;

    @Before
    public void setUp(){
        MockitoAnnotations.initMocks(this);
        userRequest = new UserRequest();

        userRequest.setFirstName("FirstName");
        userRequest.setMiddleInitial("M");
        userRequest.setLastName("LastName");
   }

    @Test
    public void validateUserRequest_testFirstName() throws Exception {

        userRequest.setFirstName(null);
        RequestWrapper requestWrapper = new RequestWrapper();
        requestWrapper.setRequest(userRequest);

        Errors errors = new BeanPropertyBindingResult(requestWrapper, "requestWrapper");
        userRequestValidator.validate(requestWrapper, errors);

        assertTrue(errors.hasErrors());
        assertNotNull(errors.getFieldError("firstName"));
    }
  //More tests

}

When I run the test i get the below exception.

java.lang.AssertionError
    at org.junit.Assert.fail(Assert.java:92)
    at org.junit.Assert.assertTrue(Assert.java:43)
    at org.junit.Assert.assertTrue(Assert.java:54)
    at com.user.validator.UserRequestValidatorTest.validateUpdateUserRequest_testFirstName(UserRequestValidatorTest.java:79)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

I am providing values so that the first name validation throws null error. Cannot understand what I am writing incorrect which is not able to validate the fields.

The exception that is mentioned is occurring at assertTrue(errors.hasErrors()) Even the next line assertNotNull(errors.getFieldError("firstName")) is also failing with the same error.

Can someone review and help me on this.

Thanks

Upvotes: 2

Views: 6948

Answers (1)

Nirmalya
Nirmalya

Reputation: 205

Ok So, First I made a blasphemous mistake of making the SmartValidator as @mock. This means that my validations were actually not executed. This was really foolish. Second, even when I removed the @mock from Smartvalidator it still didn't work. Coz I needed to inject the instance of SmartValidator in to my validation class UserRequestValidator. Hence I used the below annotations on the test class. Also I marked the validator in the test class as Autowired. That solved it.

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
public class UserRequestValidatorTest{
    @Autowired
    UserRequestValidator userRequestValidator;

    //Remaining things same as in question

}

Upvotes: 3

Related Questions