1. Обзор
Если мы разрабатываем приложение , которое использует Amazon DynamoDB , может быть сложно разработать интеграционные тесты без локального экземпляра.
В этом уроке мы рассмотрим несколько способов настройки, запуска и остановки локального DynamoDB для наших интеграционных тестов .
Этот учебник также дополняет нашу существующую статью DynamoDB .
2. Конфигурация
2.1. Настройка Maven
DynamoDB Local – это инструмент, разработанный Amazon, который поддерживает все API DynamoDB. Он не манипулирует непосредственно фактическими таблицами DynamoDB в производстве, а выполняет их локально.
Во-первых, мы добавляем локальную зависимость DynamoDB в список зависимостей в нашей конфигурации Maven:
com.amazonaws DynamoDBLocal 1.11.86 test
Затем нам также необходимо добавить репозиторий Amazon DynamoDB, поскольку зависимость не существует в центральном репозитории Maven.
Мы можем выбрать ближайший сервер Amazon к нашему текущему IP-адресу геолокации:
dynamodb-local DynamoDB Local Release Repository https://s3-us-west-2.amazonaws.com/dynamodb-local/release
2.2. Добавьте зависимость SQLite4Java
Локальный DynamoDB использует библиотеку SQLite4Java внутри; таким образом, нам также необходимо включить файлы библиотеки при запуске теста. Файлы библиотеки SQLite4Java зависят от среды, в которой выполняется тест, но Maven может извлекать их транзитивно, как только мы объявим зависимость DynamoDBLocal.
Затем нам нужно добавить новый шаг сборки для копирования собственных библиотек в определенную папку, которую мы позже определим в системном свойстве JVM.
Давайте скопируем транзитивно извлеченные файлы библиотеки SQLite4Java в папку с именем native-libs :
org.apache.maven.plugins maven-dependency-plugin 2.10 copy test-compile copy-dependencies test so,dll,dylib ${project.basedir}/native-libs
2.3. Установите системное свойство SQLite4Java
Теперь мы будем ссылаться на ранее созданную папку (где находятся библиотеки SQLite4Java), используя системное свойство JVM с именем sqlite4java.library.path :
System.setProperty("sqlite4java.library.path", "native-libs");
Чтобы успешно выполнить тест позже, необходимо, чтобы все библиотеки SQLite4Java находились в папке, определенной свойством sqlite4java.library.path system. Мы должны запустить 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 для запуска интеграционных тестов.
Как всегда, исходный код и пример конфигурации можно найти на Github .