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 .