Как выполнить аудит в службе ConstraintValidator

Я пишу свое приложение, используя Spring MVC. Я хочу проверить, существует ли электронная почта в базе данных, когда пользователь регистрируется. Я написал собственное ограничение annotations с именем UniqueEmail .

Мой пользовательский объект User.java :

@Entity @Table(name="users") public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; @Column(name = "email", length = 100, nullable = false, unique = true) @NotEmpty @Email @UniqueEmail(message = "E-mail is not unique") private String email; @Column(name = "password", nullable = false) @NotEmpty @Size(min = 5, message = "size must be more 5") private String password; } 

Мое ограничение annotations UniqueEmail.java :

 @Target({FIELD}) @Retention(RUNTIME) @Constraint(validatedBy = UniqueEmailValidator.class) @Documented public @interface UniqueEmail { String message() default "Email is exist"; Class[] groups() default {}; Class[] payload() default {}; } 

Мой валидатор UniqueEmailValidator.java :

 @Component public class UniqueEmailValidator implements ConstraintValidator { @Autowired private UserService userService; @Override public void initialize(UniqueEmail uniqueEmail) { } @Override public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) { try { return userService.isExistEmail(s); } catch (Exception e) { System.out.println(e); return false; } } } 

Этот код работает в приложении.

Когда я запускаю свой тестовый код, он возвращает исключение NullPointerException. В моем classе проверки userService имеет значение null.

Я прочитал http://docs.spring.io/spring/docs/3.0.0.RC3/reference/html/ch05s07.html, но не может решить какое-либо решение.

Есть идеи?

Обновить

Я использую JUnit. UserClassTest.java

 @ContextConfiguration("file:src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml") public class UserClass { private static Validator validator; @BeforeClass public static void setup() { ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); validator = factory.getValidator(); } @Test public void emailIsUnique() { User user = new User(); user.setEmail("mail@example.com"); // I've written exist email in DB. Set<ConstraintViolation> constraintViolations = validator.validateProperty(user, "email"); assertEquals(1, constraintViolations.size()); assertEquals("E-mail is not unique", constraintViolations.iterator().next().getMessage()); } } - @ContextConfiguration("file:src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml") public class UserClass { private static Validator validator; @BeforeClass public static void setup() { ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); validator = factory.getValidator(); } @Test public void emailIsUnique() { User user = new User(); user.setEmail("mail@example.com"); // I've written exist email in DB. Set<ConstraintViolation> constraintViolations = validator.validateProperty(user, "email"); assertEquals(1, constraintViolations.size()); assertEquals("E-mail is not unique", constraintViolations.iterator().next().getMessage()); } } 

Обновить

        /WEB-INF/tiles.xml          <mvc:resources mapping="/fonts/**" location="/resources/  

У вас нет валидатора, настроенного в контексте компонента. Если вы загружаете валидатор через Validation.buildDefaultValidatorFactory (); вы обходите механизм пружины, и вы получаете валидатор, который не знает о компонентах весны и компонентах. Следовательно, инъекция не работает. В вашем тесте вы хотите заполучить Spring Validator.

Если ваш основной код работает, то он должен быть прямым, чтобы ваш тест работал. Вы должны использовать @ContextConfiguration в своем тестовом classе, см. Это для более подробной информации: http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/testing.html

В общем, есть два способа проверить это:

  • модульный тест
  • интеграционный тест

Для модульного теста вам нужно создать экземпляр UniqueEmailValidator и установить UserService в этом экземпляре (обычно это mock UserServer).

Для теста интеграции вы должны иметь исходный контекст, как было указано выше.

Вы можете называть инъекцию всеми услугами @Autowired:

 @Override public void initialize(UniqueEmail uniqueEmail) { org.springframework.web.context.support.SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); }