解决 @Validate 在 Service 层的单元测试不生效(二)

前面记录的第一种方式与其说是单测更像是集成测试,将方法的入口参数和方法里面的业务逻辑一起给测试了,写法也稍微复杂些,更重要的是多个测试案例一起跑可能会相互有影响。

service 层的测试可以将 方法入口参数 和 方法中的业务逻辑分开做单测,因为最终的目的是让整个项目有一个较为全面的单测覆盖,以便日后可以很有底气的做重构。

service 层的方法:

public void createNewUser(CreateUserCommand createUserCommand);

方法入口参数长这个样子,要校验 name 是不是已经存在。

public class CreateUserCommand {
  @NotBlank
  @UserNameExistConstraint // name不能重复
  private String name;

  @Min(value = 1)
  private int age;

  public CreateUserCommand(String name, int age) {
    this.name = name;
    this.age = age;
  }
}

// ---
@Documented
@Constraint(validatedBy = UserNameExistValidator.class)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserNameExistConstraint {
  String message() default "{user.name.exist}";

  Class[] groups() default {};

  Class[] payload() default {};
}

// ---
@Component
public class UserNameExistValidator
    implements ConstraintValidator<UserNameExistConstraint, String> {

  @Autowired private UserRepository userRepository;

  @Override
  public boolean isValid(String name, ConstraintValidatorContext context) {
    // 从数据库中查下 name 是不是已经有了。
      if (userRepository.ofId(name).isPresent()) {
      return false;
    }
    return true;
  }
}

这里为 createUserCommand 单独写单测。

@RunWith(SpringRunner.class)
@Import(LocalValidatorFactoryBean.class)
public class ResourceDeletedValidatorTest {
  @MockBean private UserRepository userRepository;

  @Autowired private Validator validator;

  @Test
  public void should_throw_exception_when_name_is_existed() {
    String name = "new-name";
    User user = Mockito.mock(User.class);
    when(userRepository.ofId(eq(name))).thenReturn(Optional.of(user));

    Set<ConstraintViolation<CreateUserCommand>> constraintViolations =
        validator.validate(new CreateUserCommand(name,"20"));

    assertTrue(constraintViolations.size() == 1);
  }
}

这种方式让单测变的更单一些,而且写法也简单。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值