Writing JUnit tests for Spring Validator implementation

后端 未结 2 794
小蘑菇
小蘑菇 2020-12-08 20:09

I\'m using Spring Validator implementations to validate my object and I would like to know how do you write a unit test for a validator like this one:

public         


        
相关标签:
2条回答
  • 2020-12-08 20:48

    Here is the code that shows how to unit test for validation:

    1) The main Validator class for which one needs to write unit test:

    public class AddAccountValidator implements Validator {
    
        private static Logger LOGGER = Logger.getLogger(AddAccountValidator.class);
    
        public boolean supports(Class clazz) {
            return AddAccountForm.class.equals(clazz);
        }
    
        public void validate(Object command, Errors errors) {
            AddAccountForm form = (AddAccountForm) command;
            validateFields(form, errors);
        }
    
        protected void validateFields(AddAccountForm form, Errors errors) {
            if (!StringUtils.isBlank(form.getAccountname()) && form.getAccountname().length()>20){
                LOGGER.info("Account Name is too long");
                ValidationUtils.rejectValue(errors, "accountName", ValidationUtils.TOOLONG_VALIDATION);
            }
        }
    }
    

    2) Utility class supporting 1)

    public class ValidationUtils {
        public static final String TOOLONG_VALIDATION = "toolong";
    
        public static void rejectValue(Errors errors, String fieldName, String value) {
            if (errors.getFieldErrorCount(fieldName) == 0){
                errors.rejectValue(fieldName, value);
            }
        }
    }
    

    3) Here is the unit test:

    import static org.junit.Assert.assertEquals;
    import static org.junit.Assert.assertNull;
    
    import org.junit.Test;
    import org.springframework.validation.BeanPropertyBindingResult;
    import org.springframework.validation.Errors;
    
    import com.bos.web.forms.AddAccountForm;
    
    public class AddAccountValidatorTest {
    
        @Test
        public void validateFieldsTest_when_too_long() {
            // given
            AddAccountValidator addAccountValidator = new AddAccountValidator();
            AddAccountForm form = new AddAccountForm();
            form.setAccountName(
                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1");
    
            Errors errors = new BeanPropertyBindingResult(form, "");
    
            // when
            addAccountValidator.validateFields(form, errors);
    
            // then
            assertEquals(
                    "Field error in object '' on field 'accountName': rejected value [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1]; codes [toolong.accountName,toolong.java.lang.String,toolong]; arguments []; default message [null]",
                    errors.getFieldError("accountName").toString());
        }
    
        @Test
        public void validateFieldsTest_when_fine() {
            // given
            AddAccountValidator addAccountValidator = new AddAccountValidator();
            AddAccountForm form = new AddAccountForm();
            form.setAccountName("aaa1");
            Errors errors = new BeanPropertyBindingResult(form, "");
    
            // when
            addAccountValidator.validateFields(form, errors);
    
            // then
            assertNull(errors.getFieldError("accountName"));
        }
    
    }
    
    0 讨论(0)
  • 2020-12-08 20:54

    It is a really straight forward test without any mock. (just the error-object creation is a bit tricky)

    @Test
    public void testValidationWithValidAddress() {
        AdressValidator addressValidator = new AddressValidator();
        CustomValidator validatorUnderTest = new CustomValidator(adressValidator);
    
        Address validAddress = new Address();
        validAddress.set... everything to make it valid
    
        Errors errors = new BeanPropertyBindingResult(validAddress, "validAddress");
        validatorUnderTest.validate(validAddress, errors);
    
        assertFalse(errors.hasErrors()); 
    }
    
    
    @Test
    public void testValidationWithEmptyFirstNameAddress() {
        AdressValidator addressValidator = new AddressValidator();
        CustomValidator validatorUnderTest = new CustomValidator(adressValidator);
    
        Address validAddress = new Address();
        invalidAddress.setFirstName("")
        invalidAddress.set... everything to make it valid exept the first name
    
        Errors errors = new BeanPropertyBindingResult(invalidAddress, "invalidAddress");
        validatorUnderTest.validate(invalidAddress, errors);
    
        assertTrue(errors.hasErrors());
        assertNotNull(errors.getFieldError("firstName"));
    }
    

    BTW: if you really want to make it more complicate and make it complicate by a mock, then have a look at this Blog, they use a two mocks, one for the object to test (ok, this is useful if you can not create one), and a second for the Error object (I think this is more complicated the it must be.)

    0 讨论(0)
提交回复
热议问题