GAE / Java8-Testversion (Teil 4: "Datenspeicher-Zugriffslogik")

Thema

Letztes Mal erwähnte ich den Testcode, der erstellt werden kann, wenn Maven automatisch eine Java 8-App für GAE generiert. Dieses Mal werde ich versuchen, zuerst die Datenspeicher-Zugriffslogik mit Blick auf den Test hinzuzufügen.

GAE-Testindex

Entwicklungsumgebung

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

Jeder liebt IntelliJ IDEA

Referenz

Trainieren

■ Design

Legen Sie die Spezifikationen der zu implementierenden Funktionen fest. Das Thema ist das "Book List Management" -System, das auch in GCP-Tutorials üblich ist. Um diesmal die Zugriffslogik auf den Datenspeicher zu testen, Nach dem POSTEN des "Buchnamens" wird dieser im Datenspeicher registriert.

■ Testcode

Schreiben Sie den folgenden Testcode gemäß den Spezifikationen. Bearbeiten Sie die Scheinanforderung so, dass der "Buchtitel" aus den Anforderungsparametern abgerufen werden kann. Führen Sie dann "doPost (~~)" aus, um zu überprüfen, ob der obige "Buchname" in der Art "Buch" registriert ist.

  @Test
public void POSTing des Buchtitels wird im Datenspeicher registriert() throws EntityNotFoundException, ServletException, IOException {
    /*
     * SetUp
     */
    Map<String, String[]> parameterMap = new HashMap<>();
    parameterMap.put("bookName", new String[]{"Microservice-Architektur"});
    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("Microservice-Architektur");
  }

https://github.com/sky0621/java-webapi-for-gae-study/blob/master/sky0621/src/test/java/com/example/sky0621/HelloAppEngineTest.java

Übrigens, da es sich um einen ersten Test handelt, ist der obige Testcode ein Kompilierungsfehler ohne "doPost (~~)". Wenn Sie danach nur die Definition von "doPost (~~)" schreiben und den Testcode ausführen, ist dies wie folgt. Die Logik zum Registrieren des als Anforderungsparameter übergebenen "Buchnamens" im Datenspeicher ist nicht implementiert, daher ist dies ein natürliches Ergebnis. Entscheiden Sie in Test First zunächst die Spezifikationen und schreiben Sie den Testcode, um sie zu bestätigen. (Zu diesem Zeitpunkt wird es nicht kompiliert, aber es ist wichtig, von dort aus zu beginnen.) Bestehen Sie den Test zuerst. Ich weiß, dass es scheitern wird, aber ich wage es zu scheitern. Da dies vor der Implementierung der Logik geschieht, ist das Ergebnis der Testausführung NG. Wenn Sie dies zuerst überprüfen, ist es sinnvoll, dass das Ergebnis der Testausführung nach der Implementierung der Logik in Ordnung ist. (Wenn Sie nicht bestätigen, dass es zuerst fehlschlägt, wurde möglicherweise nicht der richtige Bestätigungscode geschrieben, das Ergebnis der Testausführung war möglicherweise von Anfang an in Ordnung, und es wird möglicherweise zu einem Testcode, der nicht getestet wurde, dass er korrekt implementiert wurde. Weil es gibt)


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.Wenn Sie den Buchnamen veröffentlichen, wird er im Datenspeicher registriert.(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 Uhr 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

Nachdem der Test wie erwartet fehlgeschlagen ist, ist es endlich Zeit, die Registrierungslogik für den Datenspeicher zu implementieren.

■ Implementierung

So was. Es ist keine Ebene, die mit dem Produktcode verwendet werden kann, aber vorerst ist dies der Code, der den "Buchnamen" aus den Anforderungsparametern erfasst und in Datastoreni registriert.


  @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

Wenn Sie den Testcode nach dieser Implementierung ausführen, ist das Testergebnis diesmal in Ordnung.

Zusammenfassung

Wenn Sie es zuerst testen, wird es einige Zeit dauern, bis auch nur eine kleine Funktion implementiert ist. "Angemessene Zeit" umfasst jedoch die Überprüfung der Spezifikationen, die Implementierung, den Komponententest, das Refactoring, die Kosten für die Reduzierung von Nacharbeiten usw., sodass dies für die Kostenleistung wirklich gut ist.

Recommended Posts

GAE / Java8-Testversion (Teil 4: "Datenspeicher-Zugriffslogik")
GAE / Java8-Testversion (Teil 6: "Bereitstellungsfehler")
GAE / Java8-Testversion (Teil 5: "Konsole für die lokale Entwicklung")
Zugriffsmodifikator [Java]
Java-Übung Teil 1
Greifen Sie über Java auf API.AI zu
Informationen zu Java-Zugriffsmodifikatoren
Java studieren ~ Teil 8 ~ Besetzung