文档章节

深入探索:单元测试之异常测试

灯-塔
 灯-塔
发布于 2017/09/10 22:37
字数 976
阅读 17
收藏 0

相关文章

预期异常

如果我们测试知道这个方法是要抛出异常才是我们所期望的,不然就是测试失败,我们要如何验证呢?验证码完成通常是重要的,但是确保代码在特殊情况下的行为(如:异常,状态,超时,etc)同样重要。 举个例子:

new ArrayList<Object>().get(0);

这无疑无抛出IndexOutOfBoundsException,简称IOOBE。在@Test注解中,存在一个excepted参数,可以知道方法会抛出我们预期的异常。如果我们想去验证ArraryList 抛出正确的异常,我们可以这样写:

@Test(expected = IndexOutOfBoundsException.class) 
public void empty() { 
     new ArrayList<Object>().get(0); 
}

这个excepted 参数应该是我们所应该关心的,如果这个执行方法抛出IOOBE,那么这个方法将会通过测试。是不是用起来很简单,很爽。然而,这个方法并不是如理想中那么简单,万能的。其实官方推荐的是使用 ExceptedException rule, 来实现。

下面我举一个比较极端的一个例子吧! 如果我要测试一个方法,我遇见他会是超时的,终会抛出超时异常: 我们可以这样写:

    @Test(timeout = 1000,expected = TestTimedOutException.class)
    public void testA() {
        System.out.println("first");
        for (;;){}// 必然会抛出超时异常
    }

我预测,他终会抛出异常超时,但是它仍然是无法通过测试的,这样的情况我们要如何做呢? 好吧,我们就试试project B, 按照官方推荐的试试:

    @Rule
    public ExpectedException thrown = ExpectedException.none();
    @Test(timeout = 1000)
    public void testB() {
        thrown.expect(TestTimedOutException.class);
        for(;;){}
    }

这样就能完好的通过测试。当然,@Test(timeout=1000) 也是可以用** @Rule public Timeout globalTimeout = Timeout.seconds(1000); ** 来替代的,后面会讲到,大家耐心一点哈!

深入探索异常测试(使用@Rule)

上面的方法对简单的情况很有用,但也有它的局限性。例如,您不能在异常中测试消息的值,或者在抛出异常后对域对象的状态进行测试(如订单业务的 下单状态、支付状态、退款状态这种比较常见),etc。

Try/Catch 实现

在JUnit3.x 是通过 Try/Catch 来实现的

@Test
public void testExceptionMessage() {
    try {
        new ArrayList<Object>().get(0);
        fail("Expected an IndexOutOfBoundsException to be thrown");
    } catch (IndexOutOfBoundsException anIndexOutOfBoundsException) {
        assertThat(anIndexOutOfBoundsException.getMessage(), is("Index: 0, Size: 0"));
    }
}

ExpectedException Rule

另外,使用ExpectedException rule . 此规则不仅可以指示您期望的异常情况,还可以指示预期的异常消息:

@Rule
public ExpectedException thr = ExpectedException.none();

@Test
public void shouldTestExceptionMessage() throws IndexOutOfBoundsException {
    List<Object> list = new ArrayList<Object>();
    // 预测异常
    thr.expect(IndexOutOfBoundsException.class);
    thr.expectMessage("Index: 0, Size: 0");
    list.get(0); // execution will never get past this line
}

也可以让你的expectmessage使用匹配器,这使你在你的测试更多的灵活性。一个例子:

thrown.expectMessage(Matchers.containsString("Size: 0"));

引入匹配器,需要org.hamcrest 的jar 包。 此外,您可以使用匹配检查异常,如果它具有嵌入式状态你想验证。例如:

import static org.hamcrest.Matchers.hasProperty;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.startsWith;

import javax.ws.rs.NotFoundException;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

public class TestExy {
    @Rule
    public ExpectedException thrown = ExpectedException.none();

    @Test
    public void shouldThrow() {
        TestThing testThing = new TestThing();
        thrown.expect(NotFoundException.class);
        thrown.expectMessage(startsWith("some Message"));
        thrown.expect(hasProperty("response", hasProperty("status", is(404))));
        testThing.chuck();
    }

    private class TestThing {
        public void chuck() {
            Response response = Response.status(Status.NOT_FOUND).entity("Resource not found").build();
            throw new NotFoundException("some Message", response);
        }
    }
}

© 著作权归作者所有

共有 人打赏支持
灯-塔
粉丝 2
博文 39
码字总数 63914
作品 0
广州
程序员
Android、JUnit深入浅出(一)——JUnit初步解析

Android、JUnit深入浅出(一)——JUnit初步解析 Android SDK 1.5已经将JUnit包含进来了,但是一直没有去深入了解,以前在使用一些C++的开源库中学习过与CPPUnit,简要分析过其主要框架,如下...

庸人谷
2012/12/26
0
0
测试基础介绍

迅速找出重要程序问题 1.首先测试经过变更的部分,然后测试没有变化的部分,修改和更改都意味着新的风险 2.首先测试核心功能,然后测试辅助功能,测试产品所完成的关键和常用功能,测试完成产...

测试猴
01/02
0
0
Robolectric 探索之路

layout: post title: Roboletric探索之路,从抗拒到依赖 description: Roboletric Android Unit Testing category: blog --- 我为什么以前抗拒Android Unit Testing 1、懒,人类最大的天敌;...

ice_Anson
2016/03/16
129
0
如何高效进行白盒单测

之前为写了写单元测试的基础原理和简单的环境调试,这次就简述一下在进行单元测试是需要注意的东西和基础框架。 首先,要做好单测,首先要捋清楚开发的代码结构,为成功搭建单测环境奠定基础...

fiawfo
2016/11/23
60
0
落地TDD,需要知道的

TDD TDD是个好东西,推广时,需从Why/what/how来说明别人,结合最近看的一些资料,来说明一下问题: 1、单元测试的理由 《[高效程序员的45个习惯:敏捷开发修炼之道》中已经对于单元测试好处...

通爸
2017/12/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

7月13日任务 for、while、break跳出、ontinue结束、exit退出

20.10 for循环 语法:for 变量名 in 条件; do …; done 案例1:计算1到100的和 #!/bin/bashsum=0for i in `seq 1 100`do    sum=$[$sum+$i]    echo $idoneecho $sum 案例2...

吕湘颖
37分钟前
0
0
qemu增量镜像的好处

可以快速恢复,相当于快照的功能。

simpower
45分钟前
0
0
Python3_Appium_QQ 实战

Python3_Appium实战 -海盐 APPium移动自动化测试 样例中 测试的 app 使用的是 QQ; Appium介绍 Appium 是一个自动化测试开源工具,支持 iOS 平台和 Android 平台上的原生应用,web 应用和混合...

海盐宝宝
45分钟前
0
0
内网穿透利器-ngrok的图文安装

使用场景: 在做微信开发或是调银行或支付宝等支付系统的时候,本地想联调但是对方需要可以访问的域名或是外网IP才可以。但是,在本地如果不在路由器上做映射或是公司没有固定的外网IP。这种...

中凯_凯哥java
50分钟前
2
1
归约与分组 - 读《Java 8实战》

区分Collection,Collector和collect 代码中用到的类与方法用红框标出,可从git库中查看 收集器用作高级归约 // 按货币对交易进行分组Map<Currency, List<Transaction>> currencyListMap = g...

yysue
50分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部