Интеграционное тестирование с локальным экземпляром DynamoDB

1. Обзор

Если мы разрабатываем приложение, которое использует Amazon DynamoDB , может быть сложно разработать интеграционные тесты без локального экземпляра.

В этом руководстве мы рассмотрим несколько способов настройки, запуска и остановки локальной DynamoDB для наших интеграционных тестов .

Этот учебник также дополняет нашу существующую ссылку:/spring-data-Dynamodb[статья DynamoDB].

2. Конфигурация

2.1. Maven Setup

DynamoDB Local - это инструмент, разработанный Amazon, который поддерживает все API-интерфейсы DynamoDB. Он напрямую не манипулирует действительными таблицами DynamoDB в производственном процессе, а выполняет их локально.

Сначала мы добавляем зависимость DynamoDB Local в список зависимостей в нашей конфигурации Maven:

<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>DynamoDBLocal</artifactId>
    <version>1.11.86</version>
    <scope>test</scope>
</dependency>

Затем нам также необходимо добавить хранилище Amazon DynamoDB, поскольку в хранилище Maven Central не существует зависимости.

Мы можем выбрать ближайший сервер Amazon к нашему текущему геолокации IP-адреса:

<repository>
    <id>dynamodb-local</id>
    <name>DynamoDB Local Release Repository</name>
    <url>https://s3-us-west-2.amazonaws.com/dynamodb-local/release</url>
</repository>

2.2. Добавить зависимость SQLite4Java

DynamoDB Local использует внутреннюю библиотеку SQLite4Java ; таким образом, мы также должны включить библиотечные файлы при запуске теста. Файлы библиотеки SQLite4Java зависят от среды, в которой выполняется тест, но Maven может получить их транзитивно, как только мы объявим зависимость DynamoDBLocal.

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

Давайте скопируем файлы библиотеки SQLite4Java с транзитивным доступом в папку с именем native-libs :

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.10</version>
    <executions>
        <execution>
            <id>copy</id>
            <phase>test-compile</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <includeScope>test</includeScope>
                <includeTypes>so,dll,dylib</includeTypes>
                <outputDirectory>${project.basedir}/native-libs</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

** 2.3. Установить системное свойство SQLite4Java

**

Теперь мы будем ссылаться на ранее созданную папку (в которой расположены библиотеки SQLite4Java), используя системное свойство JVM с именем sqlite4java.library.path :

System.setProperty("sqlite4java.library.path", "native-libs");

Чтобы успешно запустить тест позже, обязательно иметь все библиотеки SQLite4Java в папке, определенной системным свойством sqlite4java.library.path . Мы должны запустить Maven test-compile ( mvn test-compile ) хотя бы один раз , чтобы выполнить предварительное условие.

** 3. Настройка жизненного цикла тестовой базы данных __

__ **

Мы можем определить код для создания и запуска локального сервера DynamoDB в методе установки, аннотированном с помощью @ BeforeClass; , и симметрично остановить сервер методом разрыва, аннотированным @ AfterClass .

В следующем примере мы запустим локальный сервер DynamoDB на порту 8000 и убедимся, что он снова остановился после выполнения наших тестов:

public class ProductInfoDAOIntegrationTest {
    private static DynamoDBProxyServer server;

    @BeforeClass
    public static void setupClass() throws Exception {
        System.setProperty("sqlite4java.library.path", "native-libs");
        String port = "8000";
        server = ServerRunner.createServerFromCommandLineArgs(
          new String[]{"-inMemory", "-port", port});
        server.start();
       //...
    }

    @AfterClass
    public static void teardownClass() throws Exception {
        server.stop();
    }

   //...
}

Мы также можем запустить локальный сервер DynamoDB на любом доступном порту вместо фиксированного, используя java.net.ServerSocket . В этом случае мы также должны сконфигурировать тест для установки конечной точки на правильный порт DynamoDB :

public String getAvailablePort() throws IOException {
    ServerSocket serverSocket = new ServerSocket(0);
    return String.valueOf(serverSocket.getLocalPort());
}

4. Альтернативный подход: использование @ ClassRule

Мы можем заключить предыдущую логику в правило JUnit, которое выполняет то же действие:

public class LocalDbCreationRule extends ExternalResource {
    private DynamoDBProxyServer server;

    public LocalDbCreationRule() {
        System.setProperty("sqlite4java.library.path", "native-libs");
    }

    @Override
    protected void before() throws Exception {
        String port = "8000";
        server = ServerRunner.createServerFromCommandLineArgs(
          new String[]{"-inMemory", "-port", port});
        server.start();
    }

    @Override
    protected void after() {
        this.stopUnchecked(server);
    }

    protected void stopUnchecked(DynamoDBProxyServer dynamoDbServer) {
        try {
            dynamoDbServer.stop();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

Чтобы использовать наше пользовательское правило, нам нужно создать и аннотировать экземпляр с помощью @ ClassRule , как показано ниже. Опять же, тест создаст и запустит локальный сервер DynamoDB до инициализации тестового класса.

Обратите внимание, что модификатор доступа правила теста должен быть public для запуска теста

public class ProductInfoRepositoryIntegrationTest {
    @ClassRule
    public static LocalDbCreationRule dynamoDB = new LocalDbCreationRule();

   //...
}

Прежде чем закончить, сделайте очень короткое замечание - поскольку DynamoDB Local использует внутреннюю базу данных SQLite, ее производительность не отражает реальной производительности в производственной среде.

5. Заключение

В этой статье мы увидели, как настроить и настроить DynamoDB Local для запуска интеграционных тестов.

Как всегда, исходный код и пример конфигурации можно найти over на Github .