Essai GAE / Java8 (Partie 4: «Logique d'accès à la banque de données»)

thème

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.

Index d'essai GAE

Environnement de développement

OS

$ cat /etc/os-release 
NAME="Ubuntu"
VERSION="17.10 (Artful Aardvark)"

Java

$ 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)

IDE

Tout le monde aime IntelliJ IDEA

référence

Entraine toi

■ Conception

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.

■ Code de test

É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.

■ Mise en œuvre

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.

Résumé

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

Essai GAE / Java8 (Partie 4: «Logique d'accès à la banque de données»)
Essai GAE / Java8 (Partie 6: «Échec du déploiement»)
Essai GAE / Java8 (Partie 5: «Console pour le développement local»)
Modificateur d'accès [Java]
java pratique partie 1
Accédez à API.AI depuis Java
À propos des modificateurs d'accès Java
Étudier Java ~ Partie 8 ~ Cast