Интеграционное тестирование в Spring: TestContext Framework, конфигурация скриптов с @SqlConfig

Вы можете настроить синтаксический анализ скрипта и обработку ошибок с помощью аннотации @SqlConfig. При объявлении аннотации уровня класса для интеграционного тестового класса @SqlConfig служит глобальной конфигурацией для всех SQL-скриптов в иерархии тестовых классов. При прямом объявлении с использованием атрибута config аннотации @Sql @SqlConfig служит локальной конфигурацией для SQL сценариев, объявленных во включенной аннотации @Sql. Каждый атрибут в @SqlConfig имеет неявное значение по умолчанию, которое задокументировано в javadoc соответствующего атрибута. Из-за правил, определенных для атрибутов аннотации в Спецификации языка Java, к сожалению, невозможно присвоить значение null атрибуту аннотации. Таким образом, для поддержки переопределений унаследованной глобальной конфигурации атрибуты @SqlConfig имеют явное значение по умолчанию либо "" (для строк), {} (для массивов) или DEFAULT (для перечислений). Этот подход позволяет локальным объявлениям @SqlConfig выборочно переопределять отдельные атрибуты из глобальных объявлений @SqlConfig, предоставляя значение, отличное от "", {} или DEFAULT. Глобальные атрибуты @SqlConfig наследуются всякий раз, когда локальные атрибуты @SqlConfig не предоставляют явного значения, отличного от "", {} или DEFAULT. Таким образом, явная локальная конфигурация имеет приоритет над глобальной конфигурацией.

Параметры конфигурации, предоставляемые @Sql и @SqlConfig, эквивалентны тем, которые поддерживаются ScriptUtils и ResourceDatabasePopulator, но являются надмножеством параметров, предоставляемых элементом пространства имен <jdbc:initialize-database/>.

Управление транзакциями для @Sql

По умолчанию SqlScriptsTestExecutionListener определяет желаемую семантику транзакции для сценариев, настроенных с помощью @Sql. В частности, SQL сценарии выполняются без транзакции в рамках существующей транзакции, управляемой Spring (например, транзакции, управляемой TransactionalTestExecutionListener для теста, аннотированного с помощью @Transactional), или в изолированной транзакции, в зависимости от настроенного значения transactionMode атрибута в @SqlConfig и наличие PlatformTransactionManager в ApplicationContext теста. Однако как минимум javax.sql.DataSource должен присутствовать в ApplicationContext теста.

Если алгоритмы, используемые SqlScriptsTestExecutionListener для обнаружения DataSource и PlatformTransactionManager и вывода семантики транзакции, не соответствуют вашим потребностям, вы можете указать явные имена, установив атрибуты dataSource и transactionManager для @SqlConfig. Кроме того, вы можете управлять поведением распространения транзакции, установив атрибут transactionMode в @SqlConfig (например, должны ли скрипты запускаться в изолированной транзакции). В следующем примере показан типичный сценарий тестирования, в котором используется JUnit Jupiter и тесты транзакций с @Sql:

@SpringJUnitConfig(TestDatabaseConfig.class)
@Transactional
class TransactionalSqlScriptsTests {

    final JdbcTemplate jdbcTemplate;

    @Autowired
    TransactionalSqlScriptsTests(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }

    @Test
    @Sql("/test-data.sql")
    void usersTest() {
        // проверяем состояние в тестовой базе данных:
        assertNumUsers(2);
        // запускаем код, использующий тестовые данные...
    }

    int countRowsInTable(String tableName) {
        return JdbcTestUtils.countRowsInTable(this.jdbcTemplate, tableName);
    }

    void assertNumUsers(int expected) {
        assertEquals(expected, countRowsInTable("user"),
            "Количество записей в [user] таблице.");
    }
}

Обратите внимание, что нет необходимости очищать базу данных после запуска метода usersTest(), поскольку любые изменения, внесенные в базу данных (либо в методе тестирования, либо в сценарии /test-data.sql), автоматически откатываются TransactionalTestExecutionListener.

Слияние и переопределение конфигурации с помощью @SqlMergeMode

Начиная с Spring Framework 5.2, можно объединять объявления @Sql уровня метода с объявлениями уровня класса. Например, это позволяет вам предоставить конфигурацию для схемы базы данных или некоторых общих тестовых данных один раз для каждого тестового класса, а затем предоставить дополнительные тестовые данные для конкретного варианта использования для каждого метода тестирования. Чтобы включить слияние @Sql, аннотируйте свой тестовый класс или тестовый метод с помощью @SqlMergeMode(MERGE). Чтобы отключить слияние для определенного метода тестирования (или определенного тестового подкласса), вы можете вернуться в режим по умолчанию через @SqlMergeMode(OVERRIDE).


Читайте также:


Комментарии

Популярные сообщения из этого блога

Методы класса Object в Java

Как получить текущий timestamp в Java

Основные опции JVM для повышения производительности и отладки