【问题标题】:Parameterized junit test of custom validation in springbootspring boot中自定义验证的参数化junit测试
【发布时间】:2021-09-05 07:00:58
【问题描述】:

我在 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);
                }
        
            }
        }

【问题讨论】:

  • 您到底想要什么细节?它关于在变量级别验证整数值,我添加了错误消息
  • 你声称得到了NullPointerException,堆栈跟踪在哪里?
  • 查看更新帖

标签: java spring-boot junit junit4 customvalidator


【解决方案1】:

问题出在context mock 的配置中。

你的配置说:

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

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


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

【讨论】:

  • 能否根据我的配置提供可行的解决方案?
猜你喜欢
  • 1970-01-01
  • 2020-04-12
  • 2021-01-02
  • 1970-01-01
  • 2020-11-09
  • 1970-01-01
  • 2016-12-04
  • 2019-02-08
  • 2016-06-30
相关资源
最近更新 更多