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

}
}

问题出在contextmock的配置中。

您的配置显示:

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

但是在测试代码中传递的字符串是:"{Size.wrongSize.message}"因为此字符串与mock不匹配,所以返回null


更好的方法是在测试方法的排列部分(或在设置中(始终使用anyString()等非特定匹配器,特定匹配器(或值(仅与测试方法的断言部分中的Mockito.verify()结合使用。

最新更新