Как внедрить Validator в тест JUnit службы на основе SpringBoot? - PullRequest
0 голосов
/ 10 мая 2019

Я создаю приложение 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, похоже, не вызывается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...