Как заполнить базу данных перед запуском тестов с Micronaut

Я ищу способ выполнить некоторые сценарии SQL перед выполнением моего тестового класса. С помощью Spring я могу легко аннотировать свой тестовый класс (или тестовый метод) аннотацией @Sql. Я не нашел особого способа сделать то же самое с Micronaut.

Единственный способ, который я нашел, - это вручную заполнить данные программно в самом методе тестирования, но, по моему опыту, бывают случаи, когда вам нужно выполнить несколько вставок для проверки одного случая.

Я придумал следующий код для тестирования контроллера REST:

Код

@Validated
@Controller("/automaker")
public class AutomakerController {
    private AutomakerService automakerService;

    public AutomakerController(AutomakerService automakerService) {
        this.automakerService = automakerService;
    }

    @Get("/{id}")
    public Automaker getById(Integer id) {
        return automakerService.getById(id).orElse(null);
    }

    @Get("/")
    public List<Automaker> getAll() {
        return automakerService.getAll();
    }

    @Post("/")
    public HttpResponse<Automaker> save(@Body @Valid AutomakerSaveRequest request) {
        var automaker = automakerService.create(request);

        return HttpResponse
                .created(automaker)
                .headers(headers -> headers.location(location(automaker.getId())));

    }

    @Put("/{id}")
    @Transactional
    public HttpResponse<Automaker> update(Integer id, @Body @Valid AutomakerSaveRequest request) {
        var automaker = automakerService.getById(id).orElse(null);
        return Objects.nonNull(automaker)
                ? HttpResponse
                .ok(automakerService.update(automaker, request))
                .headers(headers -> headers.location(location(id)))
                : HttpResponse
                .notFound();
    }
}

Тестовое задание

@Client("/automaker")
public interface AutomakerTestClient {
    @Get("/{id}")
    Automaker getById(Integer id);

    @Post("/")
    HttpResponse<Automaker> create(@Body AutomakerSaveRequest request);

    @Put("/{id}")
    HttpResponse<Automaker> update(Integer id, @Body AutomakerSaveRequest request);
}
@MicronautTest
public class AutomakerControllerTest {

    @Inject
    @Client("/automaker")
    AutomakerTestClient client;

    @Test
    public void testCreateAutomakerWhenBodyIsValid() {
        var request = new AutomakerSaveRequest("Honda", "Japan");
        var response = client.create(request);
        assertThat(response.code()).isEqualTo(HttpStatus.CREATED.getCode());
        var body = response.body();
        assertThat(body).isNotNull();
        assertThat(body.getId()).isNotNull();
        assertThat(body.getName()).isEqualTo("Honda");
        assertThat(body.getCountry()).isEqualTo("Japan");
    }

    @Test
    public void testUpdateAutomakerWhenBodyIsValid() {
        var responseCreated = client.create(new AutomakerSaveRequest("Chvrolet", "Canada"));
        assertThat(responseCreated.code()).isEqualTo(HttpStatus.CREATED.getCode());
        var itemCreated = responseCreated.body();
        assertThat(itemCreated).isNotNull();
        var responseUpdated = client.update(itemCreated.getId(), new AutomakerSaveRequest("Chevrolet", "United States"));
        assertThat(responseUpdated.code()).isEqualTo(HttpStatus.OK.getCode());
        var itemUpdated = responseUpdated.body();
        assertThat(itemUpdated).isNotNull();
        assertThat(itemUpdated.getName()).isEqualTo("Chevrolet");
        assertThat(itemUpdated.getCountry()).isEqualTo("United States");
    }
}

Я мог бы использовать метод с аннотацией @Before для заполнения всех необходимых мне данных, но было бы неплохо иметь возможность использовать *.sql скрипты так, как это возможно в Spring. Есть ли способ предоставить такие *.sql сценарии до выполнения тестов?


person Leonardo Barbieri    schedule 16.10.2019    source источник


Ответы (1)


TL; DR - используйте Flyway.

С помощью Flyway вы можете (чрезвычайно) легко настроить и поддерживать заданную схему базы данных. В вашем случае любой сценарий миграции, который вы поместите в ../test/resources/db/migration/ (или любое другое местоположение по умолчанию, которое вы установили), будет виден только вашим тестам и может выполняться / запускаться автоматически (если настроен) каждый раз, когда вы запускаете свои тесты.

Другое решение - использовать базу данных в памяти (но я бы не стал этого делать для реальных приложений). Например, у H2 есть способ указать сценарий «инициализации», а другой - для заполнения данных (и т. Д.).

person x80486    schedule 18.10.2019
comment
Вы читаете мои мысли. Я собирался попробовать Flyway для этого, но, поскольку это всего лишь экспериментальный проект, я думаю, что попробую этот сценарий инициализации H2 (я не знал об этой функции). Я постараюсь опубликовать пример позже. - person Leonardo Barbieri; 21.10.2019