设为首页 加入收藏

TOP

[Android]使用自定义JUnit Rules、annotations和Resources进行单元测试(翻译)(一)
2017-10-13 10:35:43 】 浏览:2600
Tags:Android 使用 定义 JUnit Rules annotations Resources 进行 单元 测试 翻译


以下内容为原创,欢迎转载,转载请注明
来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5795091.html

使用自定义JUnit Rules、annotations和Resources进行单元测试

原文:http://www.thedroidsonroids.com/blog/android/unit-tests-rules-annotations-resources

简介

Unit Test并不只有断言和测试方法组成。它有一些可以用来提高质量和测试代码可读性的技术。在本文中我们将探索:

  • annotations
  • JUnit rules
  • java resources

背景

很多或者大多数Android apps作为一个API Client,因此需要数据格式之间的转换(通常是JSON)和POJO(数据模型类)。我们不需要在自己的代码中实现一个转换引擎而是可以使用如 GSONmoshi 等三方库来完成。

众所周知的库通常都是有很高的单元测试的覆盖率的,所以如下测试它们是没有意义的:

@Test
public void testGson() {
 //given
 Gson gson = new Gson();
 //when
 String result = gson.fromJson("\"test\"", String.class);
 //then
 assertThat(result).isEqualTo("test");
}

Listing 1. 无用的GSON单元测试.

另一方面测试解析(JSON到POJO)和生成(POJO到JSON)逻辑相关的模型类可能是有用的。如下的POJO:

public class Contributor {
 public String login;
 public boolean siteAdmin;
 public long id;
}

Listing 2. 简单POJO.

和相应的JSON:

{
    "login": "koral--",
    "id": 3340954,
    "site_admin": true
}

Listing 3. 简单JSON.

如果属性映射都正确的话,我们希望去测试它。注意属性siteAdmin使用了不同的命名风格 - Java中的驼峰命名和JSON中的蛇底命名。

简单方案

最简单的一种unit test看起来如下:

@Test
public void testParseHardcodedContributors() throws Exception {
 //given
 String json = "[\n" +
 " {\n" +
 " \"login\": \"koral--\",\n" +
 " \"id\": 3340954,\n" +
 " \"site_admin\": true\n" +
 " },\n" +
 " {\n" +
 " \"login\": \"Wavesonics\",\n" +
 " \"id\": 406473,\n" +
 " \"site_admin\": false\n" +
 " }\n" +
 "]\n";
 
 GsonBuilder gsonBuilder = new GsonBuilder();
 gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
 Gson gson = gsonBuilder.create();
 
 //when
 Contributor[] contributors;
 try (Reader reader = new BufferedReader(new StringReader(json))) {
 contributors = gson.fromJson(reader, Contributor[].class);
 }

Listing 4. 使用硬编码JSON的单元测试.

这种方法有几个弊端。最值得注意的就是比较差的JSON可读性,有大量的转义字符和没有语法高亮。此外有一点模版代码,如果有更多的JSON需要测试的话将会产生重复代码。让我们思考怎样可以用更加简便的方法来编写,提高可读性和消除代码重复率。

改进

首先Gson对象可以在测试方法外部实例化,比如使用一些像 [Dagger] (http://google.github.io/dagger) 的DI(依赖注入)机制或者使用一个简单的常量。DI已经超出了本文的范围所以我们在例子代码中使用后者。在代码提取后看起来如下:

public final class Constants {
 public static final Gson GSON;
 
 static {
 final GsonBuilder gsonBuilder = new GsonBuilder();
 gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
 GSON = gsonBuilder.create();
 }
}

Listing 5. 把GSON实例作为一个全局变量.

接着,文本形式的JSON可以被置于一个resource file中。这会给我们带来语法的高亮和缩进(漂亮的打印),默认情况下Android Studio和Intellij IDEA内置了这些功能特性。不需要引号的转义,所以可读性也不再是问题。再者,文件中的行数和列数和GSON中的一致,所以将会更加容易地像这样debug异常:MalformedJsonException: Unterminated array at line 4 column 5 path $[2]。如果JSON被放置在一个单独的文件,行数是会被确切地匹配到的,跟上述硬编码JSON的例子矛盾的地方是,需要通过java源文件中的偏移进行调整。下面是这个示例中被使用的文件:

[
  {
    "login": "koral--",
    "id": 3340954,
    "site_admin": true
  },
  {
    "login": "Wavesonics",
    "id": 406473,
    "site_admin": false
  }
]

Listing 6. 包含JSON的Java resource文件.

最后,代码执行转换可以从测试方法中提取,所以广义说它会更容易在不同的测试用例上使用。它可以使用下章将会讨论的Java和JUnit特性来实现。

Goodies

Jav

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Android 监听ScrollView的滑动 下一篇标题栏透明度变化

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目