spring boot中自定义验证的参数化junit测试
Posted
技术标签:
【中文标题】spring boot中自定义验证的参数化junit测试【英文标题】:Parameterized junit test of custom validation in springboot 【发布时间】: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
,堆栈跟踪在哪里?
查看更新帖
【参考方案1】:
问题出在context
mock 的配置中。
你的配置说:
when(context
.buildConstraintViolationWithTemplate(
"template"))
.thenReturn(builder);
但是您在被测代码中传递的字符串是:"Size.wrongSize.message"
因为这个字符串不匹配模拟返回null
。
更好的方法是在测试方法的 arrange 部分(或在 setup 中)始终使用不特定的匹配器,例如 anyString()
特定的匹配器(或值)仅在测试方法的 assert 部分中与 Mockito.verify()
结合使用。
【讨论】:
能否根据我的配置提供可行的解决方案?以上是关于spring boot中自定义验证的参数化junit测试的主要内容,如果未能解决你的问题,请参考以下文章
在 Spring Boot 中自定义异常返回空消息 [重复]