GAE/Java8试行(第三篇:Java应用测试代码解释)

请用中文翻译以下句子,仅需一种选项:

お題

在前前一次,我自动生成了一个用于GAE的Java8应用,上次我解释了主要修改的文件。
从这次开始,我打算先加入与Datastore的访问逻辑,然后再谈论测试代码。
总之,计划是先进行测试驱动开发。

GAE会试用指数

    • GAE/Java8試行(その0:「App Engineについて」)

 

    • GAE/Java8試行(その1:「Java8でWebアプリ作ってデプロイ」)

 

    GAE/Java8試行(その2:「Javaアプリ解説」)

研发环境

操作系统

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

Java – 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 (Integrated Development Environment)是一种集成开发环境的缩写。

大家都喜爱的IntelliJ IDEA。

解释的意思是对某个事物或概念进行解说或概述。

自动生成的测试代码为「HelloAppEngineTest.java」。

$ tree ※必要な部分だけ抜粋
.
└── sky0621
    ├── pom.xml
    └── src
         └── test
             └── java
                 └── com
                     └── example
                         └── sky0621
                             └── HelloAppEngineTest.java

以下是全部源代码。
https://github.com/sky0621/java-webapi-for-gae-study/blob/1a9d408da2a670ac2d61416d6ec964ae4306c8b8/sky0621/src/test/java/com/example/sky0621/HelloAppEngineTest.java

在总结的同时提取必要的部分来进行说明。

■JUnit4和mochito

@RunWith(JUnit4.class)
public class HelloAppEngineTest {
  〜省略
  @Mock private HttpServletRequest mockRequest;
  @Mock private HttpServletResponse mockResponse;
  〜省略

自动生成适用于App Engine的Maven项目时,会在”pom.xml”文件中定义以下Version。

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-all</artifactId>
      <version>1.10.19</version>
      <scope>test</scope>
    </dependency>

JUnit有最新版本的JUnit5,但在这里我们会安心地使用指定的版本。
Mockito是Java测试代码中使用模拟对象的主要工具。
只需将要模拟的对象前面加上”@Mock”注释,非常简单。

■执行测试用例前的准备工作

  @Before
  public void setUp() throws Exception {
  〜省略
  }

通过「@Before」附加,可以定义在执行每个测试用例之前应该进行的处理。

    when(mockRequest.getRequestURI()).thenReturn(FAKE_URL);
    when(mockResponse.getWriter()).thenReturn(new PrintWriter(responseWriter));

刚刚看到添加了“@Mock”注释的对象,通过这样操作可以控制其行为。(不需要解释,我觉得大致意思已经清楚了。)

■本地服务测试助手

import com.google.appengine.tools.development.testing.LocalServiceTestHelper;
  〜省略
  private final LocalServiceTestHelper helper = new LocalServiceTestHelper();
  〜省略
  @Before
  public void setUp() throws Exception {
    helper.setUp();
   〜省略
  }

通过在每个测试用例之前设置LocalServiceTestHelper,可以在使用appengine库访问GAE的Datastore或Memcache等服务时,将连接目标设置为存根,从而实现(无需通信的)连接。
通过这样做,可以编写与连接目标无关的测试代码,而不依赖于是否存在通信环境。
(测试代码应具备任何地方进行多次运行都会产生相同结果的幂等性非常重要)

■执行测试用例后处理

  @After public void tearDown() {
    helper.tearDown();
  }

通过「@After」注解可以定义在每个测试用例执行后需要执行的操作。在这里,我们可以进行设置好的LocalServiceTestHelper的清理工作。

■ 测试用例

import static com.google.common.truth.Truth.assertThat;
  〜省略
  @Mock private HttpServletRequest mockRequest;
  @Mock private HttpServletResponse mockResponse;
  private StringWriter responseWriter;
  private HelloAppEngine servletUnderTest;
  〜省略
  @Test
  public void doGet_writesResponse() throws Exception {
    servletUnderTest.doGet(mockRequest, mockResponse);

    // We expect our hello world response.
    assertThat(responseWriter.toString())
        .named("HelloAppEngine response")
        .contains("Hello App Engine - Standard ");
  }

使用提供的包而不是JUnit,传递模拟对象并对目标测试”DoGet”进行测试,并使用”assertThat”进行结果验证。

总结

一开始(当然的事情是),自动生成的测试代码是幂等的。
在保持这个不变的同时,我们将编写可测试的项目代码。
接下来,我们来写一下Datastore访问代码…

广告
将在 10 秒后关闭
bannerAds