Gymterview
middle

Как использовать Sql и SqlGroup для подготовки тестовых данных?

@Sql — аннотация Spring Test, позволяющая выполнять SQL-скрипты до или после теста для подготовки и очистки тестовых данных.

Базовое использование

Пример
@SpringBootTest
class UserServiceSqlTest {

    @Autowired
    private UserService userService;

    @Test
    @Sql("/test-data/users.sql")
    void shouldFindPreparedUsers() {
        List<User> users = userService.findAll();
        assertEquals(3, users.size());
    }

    @Test
    @Sql(
        scripts = "/test-data/cleanup.sql",
        executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD
    )
    void shouldCleanUpAfterTest() {
        // ...
    }
}

SqlGroup — группировка скриптов

Пример кода
@Test
@SqlGroup({
    @Sql(
        scripts = "/test-data/init-schema.sql",
        executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD
    ),
    @Sql(
        scripts = "/test-data/insert-users.sql",
        executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD
    ),
    @Sql(
        scripts = "/test-data/cleanup.sql",
        executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD
    )
})
void shouldWorkWithPreparedData() {
    // данные из обоих скриптов доступны
}

Инлайн SQL-выражения

Пример
@Test
@Sql(statements = {
    "INSERT INTO users (name, email) VALUES ('Тест', 'test@example.com')",
    "INSERT INTO users (name, email) VALUES ('Тест2', 'test2@example.com')"
})
void shouldWorkWithInlineSql() {
    assertEquals(2, userService.findAll().size());
}

@Sql можно применять на уровне класса — тогда скрипт будет выполняться перед каждым тестовым методом.

На собеседовании: важно знать про executionPhase (BEFORE/AFTER) и возможность инлайн SQL через statements. Частая ошибка — забыть про очистку данных после теста при использовании RANDOM_PORT (где @Transactional rollback не работает).