文档章节

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

灯-塔
 灯-塔
发布于 2017/09/10 22:37
字数 976
阅读 36
收藏 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);
        }
    }
}

© 著作权归作者所有

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

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

庸人谷
2012/12/26
0
0
如何高效进行白盒单测

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

fiawfo
2016/11/23
60
0
深入 Python :Dive Into Python 中文版 读书笔记 第13,14,15单元测试

第 13 章 单元测试 13.4. 正面测试 (Testing for success)13.5. 负面测试 (Testing for failure)测试有效输入还不够,还必需测试无效输入,而且要按预期失败形式执行13.6. 完备性检测 (Testing...

sToa
2014/03/09
0
0
如何做好接口测试?

sgbtmy:基于selenium的自动化框架开发,我主要是想问一下,你的框架除了前台的自动化,后台的数据的测试是否集成在你的测试框架中?   小刀:你好,个人理解的你所说的后台的数据的测试是...

不最醉不龟归
2016/11/13
16
0
如何做好接口测试?【转载】

sgbtmy:基于selenium的自动化框架开发,我主要是想问一下,你的框架除了前台的自动化,后台的数据的测试是否集成在你的测试框架中?   小刀:你好,个人理解的你所说的后台的数据的测试是...

红焖鲤鱼
2015/09/11
772
0

没有更多内容

加载失败,请刷新页面

加载更多

Kylin2.5.0环境搭建及操作记录

Apache Kylin是一个开源的分布式分析引擎,提供Hadoop/Spark之上的SQL查询接口及多维分析(OLAP)能力以支持超大规模数据,最初由eBay Inc. 开发并贡献至开源社区。它能在亚秒内查询巨大的H...

PeakFang-BOK
18分钟前
1
0
SpringBoot整合es

文档对像 @Document(indexName = "bigdata",type = "tag")public class User { @Idprivate String openid; private List<String> tags;public String getOpenid() ......

魔法王者安琪拉
21分钟前
1
0
windows下让 jar 在后台运行的办法

windows下 运行 java jar 不出现 命令行 窗口 新建一个披处理 run.bat,内容如下 @echo off start javaw -jar xx.jar exit 双击运行即可。...

glen_xu
30分钟前
4
0
jdk1.8 lambda stream 指定的对象属性进行去重

原因:因为Stream提供的distinct()方法只能去除重复的对象,无法根据指定的对象属性进行去重,可以应付简单场景。 解决方案: //去重,共同信息保存到bizPledgeSupplierVOs里bizPledgeSupp...

INSISTQIAO
33分钟前
0
0
vue nextTick深入理解---vue性能优化、DOM更新时机、事件循环机制

定义[nextTick、事件循环] nextTick的由来: 由于vue的数据驱动视图更新是异步的,即修改数据的当下,视图不会立即更新,而是等同一事件循环中的所有数据变化完成之后再统一进行视图更新。...

JamesView
41分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部