微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

springboot中自定义验证的参数化junit测试

如何解决springboot中自定义验证的参数化junit测试

我在 springboot 中有这个验证器,当整数不在 1 和 3 之间时会出错,我正在使用 addConstraintViolation 从属性文件打印消息

public class SizeValidator implements ConstraintValidator<SizeValidation,Integer> {
    private int maxSize = 500;
    private int minSize = 1;

    @Override
    public void initialize(SizeValidation constraintAnnotation) {
        maxSize = constraintAnnotation.mxSize();
        minSize = constraintAnnotation.minSize();
    }

    @Override
    public boolean isValid(Integer givenSize,ConstraintValidatorContext context) {
        if (givenSize > maxSize || givenSize<= minPageSize) {
            addConstraintViolation(givenSize,"{Size.wrongSize.message}",context);
            return false;
        }
        return true;
    }

    private void addConstraintViolation(Integer givenSize,String errorMessage,ConstraintValidatorContext context) {
        final HibernateConstraintValidatorContext customContext = context.unwrap(HibernateConstraintValidatorContext.class);
        customContext.addExpressionVariable("givenSize",givenSize);

        context.disableDefaultConstraintViolation();
        context.buildConstraintViolationWithTemplate(errorMessage)
                .addConstraintViolation();
    }
}

在我的validation.properties

Size.wrongSize.message=大小 ${givenSize} 的值应该在 1 之间 和 3

我想为它编写一个参数化的 junit 测试如下,但它返回 nullpointerexception 请问我哪里做错了?

 java.lang.NullPointerException
      at sizeValidator.addConstraintViolation(SizeValidator.java:33)

intellij 说它在位置

context.buildConstraintViolationWithTemplate(errorMessage) .addConstraintViolation();

import org.hibernate.validator.constraintvalidation.HibernateConstraintValidatorContext;
    import org.junit.Test;
    import org.junit.experimental.runners.Enclosed;
    import org.junit.runner.RunWith;
    import org.junit.runners.Parameterized;
    
    import javax.validation.ConstraintValidatorContext;
    import java.util.Arrays;
    import java.util.Collection;
    
    import static org.junit.Assert.assertTrue;
    import static org.mockito.ArgumentMatchers.anyString;
    import static org.mockito.ArgumentMatchers.eq;
    import static org.mockito.Mockito.mock;
    import static org.mockito.Mockito.when;
    
        @RunWith(Enclosed.class)
        public class SizeValidatorTest{
        
            @RunWith(Parameterized.class)
            public static class TestValidEntries {
                private SizeValidator validator = new SizeValidator();
                private Integer val;
        
        
                public TestValidEntries(Integer val) {
                    super();
                    this.val = val;
                }
        
                @Test
                public void test() {
                    assertTrue(isValid(val));
                }
        
                @Parameterized.Parameters(name = "{index} Valid: {0}")
                public static Collection data() {
                    return Arrays.asList(
                            -1,501
                    );
                }
        
                public boolean isValid(Integer value) {
                    final HibernateConstraintValidatorContext context = mock(HibernateConstraintValidatorContext.class);
                    when(context.unwrap(HibernateConstraintValidatorContext.class)).thenReturn(context);
                    when(context.addExpressionVariable(eq("nonUnique"),anyString())).thenReturn(context);
                    when(context.getDefaultConstraintMessageTemplate()).thenReturn("template");
                    final ConstraintValidatorContext.ConstraintViolationBuilder builder = mock(ConstraintValidatorContext.ConstraintViolationBuilder.class);
                    when(context.buildConstraintViolationWithTemplate("template")).thenReturn(builder);
        
                    when(builder.addPropertyNode(anyString())).thenReturn(mock(ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderCustomizableContext.class));
        
                    return validator.isValid(value,context);
                }
        
            }
        }

解决方法

问题在于 context 模拟的配置。

您的配置说明:

when(context
      .buildConstraintViolationWithTemplate(
          "template"))
.thenReturn(builder);

但是您在测试代码中传递的字符串是:"{Size.wrongSize.message}" 因为这个字符串不匹配模拟返回null


更好的方法是始终在测试方法的 arrange 部分(或在 setup 中)使用非特定匹配器,例如 anyString() 特定匹配器(或values) 仅与测试方法的 assert 部分中的 Mockito.verify() 结合使用。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。