Spock 单元测试框架实战指南四 - 异常测试
这一篇主要讲使用Spock如何测试代码中抛异常的场景
背景
有些方法需要抛出异常来中断或控制流程,比如参数校验的逻辑: 不能为null,不符合指定的类型,list不能为空等验证,如果校验不通过则抛出checked异常,这个异常一般都是我们封装的业务异常信息,比如下面的业务代码:
APIException
是我们封装的业务异常,主要包含errorCode
,errorMessage
属性:
这个大家应该都很熟悉,针对这种抛出多个不同错误码和错误信息的异常,如果我们使用Junit的方式测试,会比较麻烦,就目前我使用过的方法,如果是单个异常还好,多个的就不太好写测试代码
最常见的写法可能是下面这样:
当然可以使用junit的ExpectedException
方式:
或者使用@Test(expected = APIException.class)
注解
但这两种方式都有缺陷:
@Test
方式不能指定断言的异常属性,比如errorCode,errorMessage
ExpectedException
的方式也只提供了expectMessage的api,对自定义的errorCode不支持,尤其像上面的有很多分支抛出多种不同异常码的情况
thrown
我们来看下Spock是如何解决的,Spock内置thrown()方法,可以捕获调用业务代码抛出的预期异常并验证,再结合where表格的功能,可以很方便的覆盖多种自定义业务异常,代码如下:
主要代码就是在"验证用户信息的合法性"的测试方法里,其中在then
标签里用到了Spock的thrown()
方法,这个方法可以捕获我们要测试的业务代码里抛出的异常
thrown
方法的入参expectedException
,是我们自己定义的异常变量,这个变量放在where标签里就可以实现验证多种异常情况的功能(intellij idea格式化快捷键可以自动对齐表格)
expectedException
的类型是我们调用的validateUser
方法里定义的APIException
异常,我们可以验证它的所有属性,errorCode、errorMessage是否符合预期值
另外在where标签里构造请求参数时调用的getUser()
方法使用了groovy的闭包功能,即case里面的condition1
,condition2
的写法
groovy的闭包(closure) 类似Java的lambda表达式,这样写主要是为了复用之前的请求参数,所以使用了闭包,当然也可以使用传统的new对象之后,setXXX的方式构造请求对象
评论