首页 测试 体会 查看内容

如何实现Java测试的自定义断言

2014-8-5 23:13| 发布者: tianzc| 查看: 788| 评论: 0

摘要:   对于测试来说,编写断言似乎很简单:我们只需要对结果和预期进行比较,通常使用断言方法进行判断,例如测试框架提供的assertTrue()或者assertEquals()方法。然而,对于更复杂的测试场景,使用这些基础的断言验证 ...
private void assertThatRangeExists(List<Range> ranges, int rangeNb,String start, String stop) throws ParseException {assertEquals(ranges.get(rangeNb).getStart(), SDF.parse(start).getTime());assertEquals(ranges.get(rangeNb).getEnd(), SDF.parse(stop).getTime());}@Testpublic void shouldReturnHourlyRanges() throws ParseException {// givenDate dateFrom = SDF.parse("2012-07-23 12:00");Date dateTo = SDF.parse("2012-07-23 15:00");// whenfinal List<Range> ranges = HourlyRange.getRanges(dateFrom, dateTo);// thenassertEquals(ranges.size(), 3);assertThatRangeExists(ranges, 0, "2012-07-23 12:00", "2012-07-23 13:00");assertThatRangeExists(ranges, 1, "2012-07-23 13:00", "2012-07-23 14:00");assertThatRangeExists(ranges, 2, "2012-07-23 14:00", "2012-07-23 15:00");}  这样是不是好些?我会说是的。减少了重复代码的数量,提高了可读性,这当然是件好事。  这种方法的另一个优势是,我们现在可以更容易地改善验证失败时的错误信息。因为断言代码被抽到了一个方法中,所以我们可以改善断言,很容易地提供更可读的错误信息。  为了更好地复用这些断言方法,可以将它们放到测试类的基类中。  不过,我觉得我们也许能做得更好:使用私有方法也有缺点,随着测试代码的增长,很多测试方法都将使用这些私有方法,其缺点将更加明显:  断言方法的命名很难清晰反映其校验的内容。  随着需求的增长,这些方法将会趋向于接收更多的参数,以满足更复杂检查的要求。(assertThatRangeExists()现在有4个参数,已经太多了!)  有时候,为了在多个测试中复用这些代码,会在这些方法中引入一些复杂逻辑(通常以布尔标志的形式校验它们,或在某些特殊的情况下,忽略它们)。  从长远来看,所有使用私有断言方法编写的测试,意味着在可读性和可维护性方面将会遇到一些问题。我们来看一下另外一种没有这些缺点的解决方案。  匹配器类库  在我们继续之前,我们先来了解一些新工具。正如之前提到的,JUnit或者TestNG提供的断言缺少足够的灵活性。在Java世界,至少有两个开源类库能够满足我们的需求:AssertJ(FEST Fluent Assertions项目的一个分支)和 Hamcrest。我倾向于第一个,但这只是个人喜好。这两个看起来都非常强大,都能让你取得相似的效果。我更倾向于AssertJ的主要原因是它基于Fluent接口,而IDE能够完美支持该接口。  集成AssertJ和JUnit或者TestNG非常简单。你只要增加所需的import,停止使用测试框架提供的默认断言方法,改用AssertJ提供的方法就可以了。  AssertJ提供了一些现成的非常有用的断言。它们都使用相同的“模式”:先调用assertThat()方法,这是Assertions类的一个静态方法。该方法接收被测试对象作为参数,为更多的验证做好准备。之后是真正的断言方法,每一个都用于校验被测对象的各种属性。我们来看一些例子:  assertThat(myDouble).isLessThanOrEqualTo(2.0d);  assertThat(myListOfStrings).contains("a");  assertThat("some text")  .isNotEmpty()  .startsWith("some")  .hasLength(9);  从这能看出,AssertJ提供了比JUnit和TestNG丰富得多的断言集合。就像最后一个assertThat("some text")例子显示的,你甚至可以将它们串在一起。还有一个非常方便的事情是,你的IDE能够根据被测对象的类型,自动为你提示可用的方法。举例来说,对于一个double值,当你输入“assertThat(myDouble).”,然后按下CTRL + SPACE(或者其它IDE提供的快捷键),IDE将为你显示可用的方法列表,例如isEqualTo(expectedDouble)、isNegative()或isGreaterThan(otherDouble),所有这些都可用于double值的校验。这的确是一个很酷的功能。
  私有方法  那么,我们究竟能做些什么呢?好吧,最显而易见的办法是将断言抽成一个私有方法:

鲜花

握手

雷人

路过

鸡蛋

扫一扫关注最新动态

毒镜头:老镜头、摄影器材资料库、老镜头样片、摄影
爱评测 aipingce.com  
返回顶部