J’utilise DynamoDB local pour les tests unitaires. Ce n’est pas mal, mais a des inconvénients. Plus précisément:
Ce que je veux faire, c’est quelque chose comme mettre le jar local de DynamoDB, et les autres jars dont il dépend, dans mon répertoire test / resources (j’écris Java). Ensuite, avant chaque test, je le -inMemory
exécutant -inMemory
et, après le test, je l’ -inMemory
. De cette façon, quiconque arrête le repository git obtient une copie de tout ce dont il a besoin pour exécuter les tests et chaque test est indépendant des autres.
J’ai trouvé un moyen de faire cela, mais c’est moche, alors je cherche des alternatives. La solution est de mettre un fichier .zip contenant les éléments DynamoDB dans test / resources, puis dans une méthode @Before, de l’extraire dans un répertoire temporaire et de lancer un nouveau processus java pour l’exécuter. Cela fonctionne, mais c’est moche et a des inconvénients:
Il semble qu’il devrait y avoir un moyen plus facile. DynamoDB Local est, après tout, juste du code Java. Est-ce que je ne peux pas en quelque sorte demander à la JVM de se décomposer et de regarder à l’intérieur des ressources pour créer un classpath? Ou, mieux encore, ne puis-je pas simplement appeler la méthode main
de DynamoDb Local à partir d’un autre thread afin que tout se déroule en un seul processus? Des idées?
PS: Je connais Alternator, mais il semble présenter d’autres inconvénients, et je suis donc enclin à restr avec la solution prise en charge par Amazon si je parviens à le faire fonctionner.
Pour utiliser DynamoDBLocal, vous devez suivre ces étapes.
sqlite4java.library.path
pour afficher les bibliothèques natives 1. Obtenir une dépendance directe DynamoDBLocal
Celui-ci est le plus facile. Vous avez besoin de ce référentiel, comme expliqué dans les forums AWS .
com.amazonaws DynamoDBLocal 1.11.0.1 dynamodb-local DynamoDB Local Release Repository https://s3-us-west-2.amazonaws.com/dynamodb-local/release
2. Obtenir les dépendances natives SQLite4Java
Si vous n’ajoutez pas ces dépendances, vos tests échoueront avec une erreur interne 500.
Tout d’abord, ajoutez ces dépendances:
com.almworks.sqlite4java sqlite4java 1.0.392 test com.almworks.sqlite4java sqlite4java-win32-x86 1.0.392 dll test com.almworks.sqlite4java sqlite4java-win32-x64 1.0.392 dll test com.almworks.sqlite4java libsqlite4java-osx 1.0.392 dylib test com.almworks.sqlite4java libsqlite4java-linux-i386 1.0.392 so test com.almworks.sqlite4java libsqlite4java-linux-amd64 1.0.392 so test
Ajoutez ensuite ce plugin pour obtenir des dépendances natives dans un dossier spécifique:
org.apache.maven.plugins maven-dependency-plugin 2.10 copy test-comstack copy-dependencies test so,dll,dylib ${project.basedir}/native-libs
3. Définissez sqlite4java.library.path
pour afficher les bibliothèques natives
Enfin, vous devez définir la propriété système sqlite4java.library.path
dans le répertoire native-libs. Vous pouvez le faire juste avant de créer votre serveur local.
System.setProperty("sqlite4java.library.path", "native-libs");
Après ces étapes, vous pouvez utiliser DynamoDBLocal à votre guise. Voici une règle Junit qui crée un serveur local pour cela.
import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; import com.amazonaws.services.dynamodbv2.local.main.ServerRunner; import com.amazonaws.services.dynamodbv2.local.server.DynamoDBProxyServer; import org.junit.rules.ExternalResource; import java.io.IOException; import java.net.ServerSocket; /** * Creates a local DynamoDB instance for testing. */ public class LocalDynamoDBCreationRule extends ExternalResource { private DynamoDBProxyServer server; private AmazonDynamoDB amazonDynamoDB; public LocalDynamoDBCreationRule() { // This one should be copied during test-comstack time. If project's basedir does not contains a folder // named 'native-libs' please try '$ mvn clean install' from command line first System.setProperty("sqlite4java.library.path", "native-libs"); } @Override protected void before() throws Throwable { try { final Ssortingng port = getAvailablePort(); this.server = ServerRunner.createServerFromCommandLineArgs(new Ssortingng[]{"-inMemory", "-port", port}); server.start(); amazonDynamoDB = new AmazonDynamoDBClient(new BasicAWSCredentials("access", "secret")); amazonDynamoDB.setEndpoint("http://localhost:" + port); } catch (Exception e) { throw new RuntimeException(e); } } @Override protected void after() { if (server == null) { return; } try { server.stop(); } catch (Exception e) { throw new RuntimeException(e); } } public AmazonDynamoDB getAmazonDynamoDB() { return amazonDynamoDB; } private Ssortingng getAvailablePort() { try (final ServerSocket serverSocket = new ServerSocket(0)) { return Ssortingng.valueOf(serverSocket.getLocalPort()); } catch (IOException e) { throw new RuntimeException("Available port was not found", e); } } }
Vous pouvez utiliser cette règle comme ceci
@RunWith(JUnit4.class) public class UserDAOImplTest { @ClassRule public static final LocalDynamoDBCreationRule dynamoDB = new LocalDynamoDBCreationRule(); }
Vous pouvez utiliser DynamoDB Local comme dépendance de test Maven dans votre code de test, comme indiqué dans cette annonce . Vous pouvez exécuter sur HTTP:
import com.amazonaws.services.dynamodbv2.local.main.ServerRunner; import com.amazonaws.services.dynamodbv2.local.server.DynamoDBProxyServer; final Ssortingng[] localArgs = { "-inMemory" }; DynamoDBProxyServer server = ServerRunner.createServerFromCommandLineArgs(localArgs); server.start(); AmazonDynamoDB dynamodb = new AmazonDynamoDBClient(); dynamodb.setEndpoint("http://localhost:8000"); dynamodb.listTables(); server.stop();
Vous pouvez également exécuter en mode intégré:
import com.amazonaws.services.dynamodbv2.local.embedded.DynamoDBEmbedded; AmazonDynamoDB dynamodb = DynamoDBEmbedded.create(); dynamodb.listTables();
Ceci est un rappel de la réponse de bhdrkn pour les utilisateurs de Gradle (le sien est basé sur Maven). C’est toujours les trois mêmes étapes:
- Obtenir une dépendance directe DynamoDBLocal
- Obtenir des dépendances natives SQLite4Java
- Définissez sqlite4java.library.path pour afficher les bibliothèques natives
Ajoutez à la section des dépendances de votre fichier build.gradle …
dependencies { testComstack "com.amazonaws:DynamoDBLocal:1.+" }
Les bibliothèques sqlite4java seront déjà téléchargées en tant que dépendance de DynamoDBLocal, mais les fichiers de bibliothèque doivent être copiés au bon endroit. Ajoutez à votre fichier build.gradle …
task copyNativeDeps(type: Copy) { from(configurations.comstack + configurations.testComstack) { include '*.dll' include '*.dylib' include '*.so' } into 'build/libs' }
Nous devons dire à Gradle de lancer copyNativeDeps
pour le test et à sqlite4java où trouver les fichiers. Ajoutez à votre fichier build.gradle …
test { dependsOn copyNativeDeps systemProperty "java.library.path", 'build/libs' }
J’ai résumé les réponses ci-dessus dans deux règles JUnit qui ne requièrent aucune modification du script de construction car les règles gèrent les éléments de la bibliothèque native. C’est ce que j’ai fait, car j’ai constaté qu’Idea n’aimait pas les solutions Gradle / Maven.
Cela signifie que les étapes sont les suivantes:
Maven:
com.amazonaws DynamoDBLocal 1.11.0.1 test com.github.mlk assortmentofjunitrules 1.5.36 test dynamodb-local DynamoDB Local Release Repository https://s3-us-west-2.amazonaws.com/dynamodb-local/release
Gradle:
repositories { mavenCentral() maven { url = "https://s3-us-west-2.amazonaws.com/dynamodb-local/release" } } dependencies { testComstack "com.github.mlk:assortmentofjunitrules:1.5.36" testComstack "com.amazonaws:DynamoDBLocal:1.+" }
Code:
public class LocalDynamoDbRuleTest { @Rule public LocalDynamoDbRule ddb = new LocalDynamoDbRule(); @Test public void test() { doDynamoStuff(ddb.getClient()); } }
Pour les tests unitaires au travail, j’utilise Mockito, puis il suffit de simuler AmazonDynamoDBClient. puis simuler les retours en utilisant quand. comme suit:
when(mockAmazonDynamoDBClient.getItem(isA(GetItemRequest.class))).thenAnswer(new Answer() { @Override public GetItemResult answer(InvocationOnMock invocation) throws Throwable { GetItemResult result = new GetItemResult(); result.setItem( testResultItem ); return result; } });
Je ne sais pas si c’est ce que vous recherchez mais c’est comme ça que nous le faisons.
Il existe deux wrappers node.js pour DynamoDB Local. Celles-ci permettent d’exécuter facilement des tests unitaires en combinant des tâches comme gulp ou grunt. Essayez dynamodb-localhost , dynamodb-local
Dans Hadoop, nous utilisons également DynamoDBLocal pour les tests et le débogage. S’il vous plaît voir comment il est utilisé là comme exemple à: https://github.com/apache/hadoop/blob/HADOOP-13345/hadoop-tools/hadoop-aws/src/test/java/org/apache/hadoop/fs/ s3a / s3guard / TestDynamoDBMetadataStore.java # L113
J’ai trouvé que le repo d’Amazon n’avait pas d’index, donc il ne semble pas fonctionner d’une manière qui vous permette de l’introduire comme ceci:
maven { url = "https://s3-us-west-2.amazonaws.com/dynamodb-local/release" }
Le seul moyen de charger les dépendances est de télécharger DynamoDbLocal en tant que fichier jar et de l’insérer dans mon script de construction, comme suit:
dependencies { ... runtime files('libs/DynamoDBLocal.jar') ... }
Bien sûr, cela signifie que toutes les dépendances SQLite et Jetty doivent être apscopes manuellement – j’essaie toujours de le faire correctement. Si quelqu’un connaît un repo fiable pour DynamoDbLocal, j’aimerais vraiment savoir.