JUnit 4 如何正确测试异常

发表于:2015-4-07 10:43

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:元月六号    来源:51Testing软件测试网采编

  本篇讲述如何在 JUnit 4 下正确测试异常,我会从 try..catch 的方式谈起,然后说到 @Test(expected=Exception.class), 最后论及 @Rules public ExpectedException 的实现方式,最终基本可确定用 @Rules 是最方便的。
  我们在用 JUnit 测试方法异常的时候,最容易想到的办法就是用 try...catch 去捕获异常,需要断言以下几个条件:
  1. 确实抛出的异常
  2. 抛出异常的 Class 类型
  3. 抛出异常的具体类型,一般检查异常的 message 属性中包含的字符串的断定
  所以常用的代码你可能会这么写:
  @Test
  public void passwordLengthLessThan6LettersThrowsException(){
  try{
  Password.validate("123");
  fail("No exception thrown.");
  }catch(Exception ex){
  assertTrue(ex instanceof InvalidPasswordException);
  assertTrue(ex.getMessage().contains("contains at least 6"));
  }
  }
  这里被测试的方法是 Password.validate() 方法是否抛出了相应的异常,注意这里别漏 try 中的
  fail("No Exception thrown.")
  代码行,不然如果被测试的方法如果没有抛出异常的话,这个用例是通过的,而你预期的是要抛出异常的。
  上面的土办法对于哪个 JUnit 版本是是适合,可是我们早已步入了 JUnit 4 的时候,大可不必如此这般的去测试方法异常。虽然这样也能测定出是否执行出预期的异常来,但它仍有弊端,接下来会一对比就知道了,try...catch 的方法,JUnit 无法为你提示出详细的断言失败原因。
  那么来看看自从 JUnit 4 后可以怎么去测试异常呢?用 @Test(execpted=Exception.class) 注解就行,参考如下代码:
  @Test(expected = NullPointerException.class)
  public void passwordIsNullThrowsException() throws InvalidPasswordException {
  Password.validate(null);
  }
  如果被测试的方法有抛出 NullPointerException 类型便是断言成功,对了 @Test(expected = NullPointerException.class) 只能判断出异常的类型,并无相应的注解能断言出异常的更具体的信息,即无法判定抛出异常的  message 属性。
  那么,有时候我们会在一个方法中多次抛出一种类型的异常,但原因不同,即异常的 message 信息不同,比如出现 InvalidPasswordException 时会有以下两种异常:
  new InvalidPasswordException("Password must contains at least 6 letters.")
  new InvalidPasswordException("Password length less than 15 letters")
  这就要有办法去断言异常的 message 了,针对于此,自 JUnit 4.7 之后又给了我们更完美的选择,就是下面的代码:
  @Rule
  public ExpectedException expectedEx = ExpectedException.none();
  @Test
  public void passwordIsEmptyThrowsException() throws InvalidPasswordException {
  expectedEx.expect(InvalidPassrdException.class);
  expectedEx.expectMessage("required");
  Password.validate("");
  }
  上面代码需重点关注几个:
  1. @Rule 注解的  ExpectedException 变量声明,它必须为  public
  2. @Test 处,不能写成 @Test(expected=InvalidPasswordException.class),否则不能正确测试,也就是
  @Test(expected=InvalidPasswordException.class) 和测试方法中的 expectedEx.expectXxx() 方法是不能同时并存的
  3. expectedEx.expectMessage() 中的参数是 Matcher 或  subString,就是说可用正则表达式判定,或判断是否包含某个子字符串
  4. 再就是有一点很重,把被测试方法写在 expectedEx.expectXxx() 方法后面,不然也不能正确测试的异常
  5. 最后一个是,只要测试方法直接抛出被测试方法的异常即可,并不影响你所关心的异常
  前面说到用 try...catch 的办法也能正确测试到异常,@Test(expected=...) 或 @Rule 与 try...catch 的方法对比有什么好处呢,显然用 JUnit 4 推荐的方法简洁明了。再来看测试失败时 JUnit 会为你提示什么呢?
21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号