Я создаю приложение SpringBoot CRUD на основе контроллера REST, вызывающего Spring Service. Полученное POJO имеет связанные с валидацией аннотации (включая пользовательские валидаторы), и фактические валидации инициируются внутри Сервиса (см. Ниже).
Все отлично работает в исполнении SpringBoot.
Теперь мне нужно создать соответствующие юниты тестов для моей службы, т. Е. Я не хочу запустить сервер приложений через SpringBootRunner.
Ниже приведен мой класс пациента с аннотациями, относящимися к валидации.
@Data
@Entity
public class Patient {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotEmpty(message = "patient.name.mandatory")
private String name;
@Past(message = "patient.dateOfBirth.inThePast")
@NotNull(message = "patient.dateOfBirth.mandatory")
private Date dateOfBirth;
private boolean isEmergency;
// [...]
}
Это служба, вызываемая REST-контроллером SpringBoot.
@Service
@Validated
public class PatientService {
@Autowired
private PatientRepository repository;
@Autowired
private Validator validator;
public Patient create(Patient patient) {
if (! patient.isEmergency()) {
validator.validate(patient);
// then throw exception if validation failed
}
// [...]
}
}
А вот и мой тест JUnit.
@RunWith(MockitoJUnitRunner.class)
@SpringBootTest
@Import(ModalityTestConfiguration.class)
public class PatientServiceTest {
@InjectMocks
private PatientService service;
@MockBean
private PatientRepository repository;
@Autowired
private Validator validator;
@Test
public void invalidEmptyPatientNoEmergency() {
Patient p = new Patient();
Patient result = null;
try {
result = service.create(p); // validations must fail -> exception
assert(false);
} catch (ConstraintViolationException e) {
// Execution should get here to verify that validations are OK
assert(result != null);
assert(e.getConstraintViolations() != null);
assert(e.getConstraintViolations().size() != 0);
// [...]
} catch (Exception e) {
assert(false);
}
}
На всякий случай, вот контроллер REST (я думаю, что он не относится к тесту JUnit)
@RestController
public class PatientController {
@Autowired
private PatientService patientService;
@PostMapping("/patients")
Patient createPatient(@RequestBody Patient patient) {
return (patientService.create(patient));
}
Моя проблема в том, что Валидатор в моем Сервисе всегда равен нулю .
- Я попытался создать выделенный файл конфигурации с компонентом проверки
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
и привязка конфигурации к контрольному кейсу
@ContextConfiguration(locations = {"/modality-test-config.xml"})
- Я попытался определить локальный @Bean для валидатора
- Я играл с и без @ Autowire
- Я изменил @ RunWith
Я уверен, что это где-то второстепенная деталь, но я, похоже, не получаю ненулевой валидатор в тесте JUnit Сервиса.
UPDATE
Вот класс TestConfiguration, который я добавил после комментария TheHeadRush.
@TestConfiguration
public class ModalityTestConfiguration {
@Bean("validator")
public Validator validator() {
return (Validation.buildDefaultValidatorFactory().getValidator());
}
}
Я также добавил соответствующую аннотацию @Import в классе Test выше.
Все еще не повезло: поле Validator остается пустым как в классе Test, так и в Service. Кроме того, точка останова в классе TestConfiguration, похоже, не вызывается.