Dernière fois, j'ai mentionné le code de test qui peut être créé lorsque Maven génère automatiquement une application Java 8 pour GAE. Cette fois, je vais essayer d'ajouter une logique d'accès à la banque de données en pensant d'abord au test.
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="17.10 (Artful Aardvark)"
$ java -version
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)
Tout le monde aime IntelliJ IDEA
Déterminer les spécifications des fonctions à implémenter. Le thème est le système de "gestion des listes de livres", qui est également courant dans les didacticiels GCP. Pour essayer la logique d'accès à Datastore cette fois, Après avoir POSTÉ le "nom du livre", il doit être enregistré dans le magasin de données.
Écrivez le code de test suivant conformément aux spécifications.
Manipulez la demande fictive afin que le "titre du livre" puisse être obtenu à partir des paramètres de la demande.
Ensuite, exécutez doPost (~~)
pour vérifier que le "nom du livre" ci-dessus est enregistré dans le type livre
.
@Test
public void POSTER le titre du livre sera enregistré dans le magasin de données() throws EntityNotFoundException, ServletException, IOException {
/*
* SetUp
*/
Map<String, String[]> parameterMap = new HashMap<>();
parameterMap.put("bookName", new String[]{"Architecture de microservices"});
when(mockRequest.getParameterMap()).thenReturn(parameterMap);
/*
* Execute
*/
servletUnderTest.doPost(mockRequest, mockResponse);
/*
* Assert
*/
DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
Entity e = ds.get(KeyFactory.createKey("book", 1));
String microService = (String)e.getProperty("bookName");
assertThat(microService).isEqualTo("Architecture de microservices");
}
https://github.com/sky0621/java-webapi-for-gae-study/blob/master/sky0621/src/test/java/com/example/sky0621/HelloAppEngineTest.java
Au fait, puisqu'il s'agit d'un test en premier, le code de test ci-dessus est une erreur de compilation sans doPost (~~)
.
Après cela, si vous écrivez seulement la définition de doPost (~~)
et exécutez le code de test, ce sera comme suit.
La logique pour enregistrer le "nom du livre" passé en tant que paramètre de demande dans le magasin de données n'est pas implémentée, il s'agit donc d'un résultat naturel.
Dans Test First, décidez d'abord des spécifications et écrivez le code de test pour les confirmer.
(À ce stade, il ne se compilera pas, mais il est important de commencer à partir de là)
Échouez d'abord au test.
Je sais que cela échouera, mais j'ose échouer. Comme c'est avant la mise en œuvre de la logique, le résultat de l'exécution du test sera NG.
En vérifiant cela en premier, il est logique que le résultat de l'exécution du test soit OK une fois la logique implémentée.
(Si vous ne confirmez pas qu'il échoue en premier, le code de vérification correct n'a peut-être pas été écrit, le résultat de l'exécution du test peut avoir été correct depuis le début et il peut devenir un code de test qui n'a pas été testé et qui a été mis en œuvre correctement. Parce qu'il y a)
com.google.appengine.api.datastore.EntityNotFoundException: No entity was found matching the key: book("micro")
at com.google.appengine.api.datastore.BaseAsyncDatastoreServiceImpl$1.wrap(BaseAsyncDatastoreServiceImpl.java:174)
at com.google.appengine.api.datastore.BaseAsyncDatastoreServiceImpl$1.wrap(BaseAsyncDatastoreServiceImpl.java:169)
at com.google.appengine.api.utils.FutureWrapper.wrapAndCache(FutureWrapper.java:56)
at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:93)
at com.google.appengine.api.datastore.FutureHelper.getInternal(FutureHelper.java:76)
at com.google.appengine.api.datastore.FutureHelper.quietGet(FutureHelper.java:63)
at com.google.appengine.api.datastore.DatastoreServiceImpl.get(DatastoreServiceImpl.java:41)
at com.example.sky0621.HelloAppEngineTest.Lorsque vous POSTEZ le nom du livre, il sera enregistré dans le magasin de données.(HelloAppEngineTest.java:100)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
10 23, 2018 12:21:13 h 00 com.google.appengine.api.datastore.dev.LocalDatastoreService cleanupActiveServices
information: scheduler shutting down.
Disconnected from the target VM, address: '127.0.0.1:37713', transport: 'socket'
Process finished with exit code 255
Maintenant que le test a échoué comme prévu, il est enfin temps d'implémenter la logique d'enregistrement du magasin de données.
Comme ça. Ce n'est pas un niveau qui peut être utilisé avec le code produit, mais pour le moment, c'est le code qui capture le "nom du livre" à partir des paramètres de la requête et l'enregistre dans Datastoreni.
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
req.getParameterMap().forEach((k, v) -> {
Key key = KeyFactory.createKey("book", 1);
Entity e = new Entity(key);
e.setProperty("bookName", Arrays.stream(v).collect(Collectors.joining()));
ds.put(e);
});
}
https://github.com/sky0621/java-webapi-for-gae-study/blob/master/sky0621/src/main/java/com/example/sky0621/HelloAppEngine.java
Si vous exécutez le code de test après cette implémentation, le résultat du test sera OK cette fois.
Si vous le faites d'abord par le test, il faudra un certain temps pour implémenter même une petite fonction. Cependant, le «délai raisonnable» comprend la révision des spécifications, la mise en œuvre, le test unitaire, la refactorisation, la réduction des coûts de retouche, etc., donc c'est vraiment bon pour la performance des coûts.
Recommended Posts