spock(Spock单元测试框架系列(七):异常测试)
2024年01月11日 靓嘟嘟
在业务开发中,我们经常会遇到各种抛出异常的情况,
- 主动抛出异常,比如参数校验中校验不能为null,列表不能为空,不符合某种类型等,我们可能会在校验不通过时主动抛出异常。
- 主动捕获异常,比如在调用某个明确抛出异常的方法时,我们会主动捕获异常,以便打印相关异常信息,方便问题的排查。
本篇文章主要介绍一下Spock是如何测试代码中抛异常的场景,以及如何Mock一个方法抛出异常。
测试异常
以下业务代码用于校验一个用户是否合法:
/** * 校验用户是否合法 * * @param user 用户 */public void validateUser(UserDO user) { if (user == null) { throw new BizException("10001", "user is null"); } if (user.getUserId() == null || user.getUserId() <= 0) { throw new BizException("10002", "user id is invalid"); } if (StringUtils.isEmpty(user.getUserNick())) { throw new BizException("10003", "user nick is empty"); }}
在Spock中,我们可以then块中通过 thrown() 方法来验证异常,甚至可以验证异常的errorCode和errorMessage是否符合预期。
@Unrolldef "test validate user"() { when: itemService.validateUser(user) then: def exception = thrown(expectedException) exception.errorCode == expectedErrCode where: user || expectedException || expectedErrCode getUser(10001) || BizException || "10001" getUser(10002) || BizException || "10002" getUser(10003) || BizException || "10003"}def getUser(int code) { def user = new UserDO() switch (code) { case 10001: user = null break case 10002: user.setUserId(0) break case 10003: user.setUserId(123L) user.setUserNick(null) break } return user}
在Spock中,我们还可以通过 notThrown()方法测试某个方法未抛出异常。当您测试一个Void方法并且想要测试它是否在不抛出异常的情况下执行时非常有用。
还是上面的业务代码,我们增加了一种不抛出异常的验证。
@Unrolldef "test valid user"() { given: def user = new UserDO( userId: 123L, userNick: "user" ) when: itemService.validateUser(user) then: notThrown(BizException)}
模拟异常
业务中我们在调用下游的方法时,会经常通过try-catch来捕获下游主动抛出的一些异常,就像我们上面所写的校验逻辑。在这种情况下,我们除了验证正常的链路,还希望能够主动模拟下游方法抛出异常以便于验证catch中的逻辑。
在Spock中,模拟方法抛出的异常非常简单,就像模拟方法的返回值一样。以下这段代码是我们业务中的一段真实逻辑(仅用于演示,去掉了一些包含业务语义的部分)。
@Component@Slf4jpublic class OutputExt extends BlankOutputExt { @Resource private strategyManager StrategyManager; @Override public ErrorMessage process(final Context context) { try { strategyManager.parse(context.getResponse()); } catch (BizException e) { log.error("策略解析异常:", e.getErrorCode(), e.getErrorMsg()); return ErrorMessageUtils.fail(e); } return ErrorMessageUtils.success(); }}
我们来看看Spock是如何测试这段代码中catch分支的。
class OutputExtTest extends Specification { def strategyManager = Mock(StrategyManager) def outputExt = new OutputExt( strategyManager: strategyManager ) def "test process"() { given: def context = new Context( response: new ResponseDTO() ) when: strategyManager.parse(_ as ResponseDTO) >> { throw new BizException("10010", "parse error") } def errorMessage = outputExt.process(context) then: with(errorMessage) { errorCode == "10010" } }}
可以看到,通过 strategyManager.parse(_ as ResponseDTO) >> { throw new BizException("10010", "parse error") } 即可以很轻松的模拟Mock对象的方法调用抛出异常。
以上,就是本篇文章的所有内容,谢谢大家!
相关文章
- 霍邱的美女(贪色成性,匪夷所思县委书记大玩表妹梗,你敢信?)
- 美女空(美女去吃20元管饱的流水面,注意力太过集中,结果空着肚子回来了)
- 美女李治(武则天跟李世民12年都没怀孕,为何刚嫁给李治就怀了?原因很简单)
- 美女被搅肠(三年不饮湘江水,十年不食湘江鱼:血战湘江,红军用命换时间)
- 美女 壁纸高清(美女高清壁纸‖性感完美身材)
- 美女被sp(半师生(sp)④)
- 动漫美女邪恶福利漫画工(原创斗破苍穹:美杜莎女王 邪恶柔情魅力尽显 绚烂风华 突破次元界限)
- 被美女吃进肚子里(美女教师遭校长侵犯,为校长打胎三次,竟还和校长儿子搞在一起)
- 极品美女洞洞开放图片(传奇超模凯特摩丝洞洞衣+鼻环超潮,不畏素颜入镜展现最自然样貌)
- 二美女比脚(美女被拥抱并用2000元的香槟洗脚,有人帮他揉脚,有钱人真会玩)