添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
睿智的砖头  ·  segment fault 11 when ...·  1 年前    · 
豪气的消防车  ·  bpython3无法import ...·  2 年前    · 
坚强的领结  ·  MSBuild properties ...·  2 年前    · 

我们在用 JUnit 测试方法异常的时候,最容易想到的办法就是用 try…catch 去捕获异常,需要断言以下几个条件:

1. 确实抛出的异常
2. 抛出异常的 Class 类型
3. 抛出异常的具体类型,一般检查异常的 message 属性中包含的字符串的断定

所以常用的代码你可能会这么写:

  1. @Test
  2. publicvoid passwordLengthLessThan6LettersThrowsException(){
  3. try {
  4. Password.validate( "123" );
  5. fail( "No exception thrown." );
  6. } catch (Exception ex){
  7. assertTrue(exinstanceofInvalidPasswordException);
  8. assertTrue(ex.getMessage().contains( "contains at least 6" ));
  9. }
  10. }

这里被测试的方法是 Password.validate() 方法是否抛出了相应的异常,注意这里别漏 try 中的

fail(“No Exception thrown.”) 代码行,不然如果被测试的方法如果没有抛出异常的话,这个用例是通过的,而你预期的是要抛出异常的。

上面的土办法对于哪个 JUnit 版本是是适合,可是我们早已步入了 JUnit 4 的时候,大可不必如此这般的去测试方法异常。虽然这样也能测定出是否执行出预期的异常来,但它仍有弊端,接下来会一对比就知道了,try…catch 的方法,JUnit 无法为你提示出详细的断言失败原因。

那么来看看自从 JUnit 4 后可以怎么去测试异常呢?用 @Test(execpted=Exception.class) 注解就行,参考如下代码:

  1. @Test (expected = NullPointerException. class )
  2. publicvoid passwordIsNullThrowsException() throwsInvalidPasswordException {
  3. Password.validate( null );
  4. }

如果被测试的方法有抛出 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 之后又给了我们更完美的选择,就是下面的代码:

  1. @Rule
  2. publicExpectedException expectedEx = ExpectedException.none();
  3. @Test
  4. publicvoid passwordIsEmptyThrowsException() throwsInvalidPasswordException {
  5. expectedEx.expect(InvalidPasswordException. class );
  6. expectedEx.expectMessage( "required" );
  7. Password.validate( "" );
  8. }

上面代码需重点关注几个:

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 会为你提示什么呢?

try…catch 测试异常失败时,得到的提示: 无异常时:

java.lang.AssertionError: No exception thrown.
at org.junit.Assert.fail(Assert.java:91)
at cc.unmi.PasswordTest.passwordLengthLessThan6LettersThrowsException(PasswordTest.java:20)

异常类型不对或异常的 message 不对时:

java.lang.AssertionError:
at org.junit.Assert.fail(Assert.java:91)
at org.junit.Assert.assertTrue(Assert.java:43)
at org.junit.Assert.assertTrue(Assert.java:54)
at cc.unmi.PasswordTest.passwordLengthLessThan6LettersThrowsException(PasswordTest.java:22)

上面能提供给我们的定位错误的帮助不是特别大

再看 @Test(expected=InvalidPasswordException.class) 时测试失败时的提示:

java.lang.AssertionError: Expected exception: cc.unmi.InvalidPasswordException
at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:32)
at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:110)

用 @Rules ExpectedException方式来测试异常,失败时的提示:

java.lang.AssertionError: Expected: (exception with message a string containing “YES. required” and an instance of java.lang.NullPointerException) got: <cc.unmi.InvalidPasswordException: Password is required.>
at org.junit.Assert.assertThat(Assert.java:778)
at org.junit.Assert.assertThat(Assert.java:736)
at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:114)

特别是 @Rules  ExpectedException 方法时为何测试失败提示的清清楚楚。期望什么异常,异常 message 中含何字符串,实际上确得到什么类型的异常,异常中 message 是什么。有了这,你一看到就知道怎么去修补你的程序。

所以到了这里,我们真的没理由不用 @Test(expected=…) 或  @Rule ExpectedException 的写法了。

末了,还是补上一段代码,开篇的 try…catch 测试异常的代码是说明别忽略了 catch 块中的 fail() 代码行, 如果没有 fail() 那么就可以写成下面那样子的:

  1. @Test
  2. publicvoid passwordLengthMoreThan15LettersThrowsException(){
  3. Throwable t = null ;
  4. try {
  5. Password.validate( "1234567890123456" );
  6. } catch (Exception ex){
  7. t = ex;
  8. }
  9. assertNotNull(t);
  10. assertTrue(tinstanceofInvalidPasswordException);
  11. assertTrue(t.getMessage().contains( "less than 15" ));
  12. }

不过,总之呢,有了 JUnit 4 呢,不提 try…catch 的实现方式也罢。

最后附上两个我为这篇博文写的测试代码 Password.java PasswordTest.java ,点击这两文件名即可下载。这里面有种写法的测试用例,文中的代码也这里面也有,可供参考。

参考:1. JUnit 4.7的新特性:Rule
2. ExpectedException (JUnit API)
3. JUnit 4 抢先看
4. JUnit: Custom ExpectedException rules…rule!
5. Expected Exception Testing With JUnit

本文链接 http://unmi.cc/junit-4-how-to-test-exceptions/ , 来自 隔叶黄莺 Unmi Blog

这个习语是最受欢迎的习语之一,因为它已在JUnit 3中使用。 @Test public void throwsExceptionWhenNegativeNumbersAreGiven() { tr... Junit单元 测试 相关jar工具。包含:hamcrest-core-1.3和junit-4.13.1 单元 测试 (英语: Unit Testing )又称为 模块 测试 ,是针对 程序模块 ( 软件设计 的最小单位)来进行 正确 性检验的 测试 工作。. 程序单元是应用的最小可 测试 部件。. 在 过程化编程 中,一个单元就是单个程序、函数、过程等;对于面向对象编程,最小单元就是方法,包括基类(超类)、抽象类、或者派生类(子类)中的方法。. 通常来说,程式设计师每修改一次程式就会进行最少一次单元 测试 ,在编写程式的过程中前后很可能要进行多次单元 测试 ,以证实程式达到 软件规格书 要求的工作目标,没有 程序错误 ;虽然单元 测试 不是必须的,但也不坏,这牵涉到 专案管理 的政策决定。. 每个理想的 测试 案例 独立于其它案例;为 测试 时隔离模块,经常使用stubs、mock 或fake等 测试 ... 单元 测试 测试 用例要覆盖常用的输入组合、边界条件和 异常 。 单元 测试 代码要非常简单,如果 测试 代码太复杂,那么 测试 代码本身就可能有bug。 用于可维护性计算的Cucumber UI自动化 测试 Cucumber,Java,Selenium,Junit 假设:页面将 正确 加载而没有任何更长的加载时间Selenium将不会引发任何 异常 ,例如Stale Element Exceptionn,Element Not Visible Exception 局限性:将xpath用作定位器,有些地方可以使用id,以后可以考虑使用某些可重复使用的函数find_element_by_id需要用于所有可用功能,似乎并不是所有地方都已被使用UserActions文件现在太大了,这可以根据函数分为很多代码重构需要在许多地方完成,在尚未使用Class和After Class之前,此代码尚未完成浏览器关闭,因此我们必须手动关闭浏览器以保持时间 文件夹结构 存储库中的src文件夹包含2个文件夹第一个文件夹-功能 测试 (每个场景3个功能 测试 )第二个文件夹-维 COMP1206-DAGSort-JUnit-Test 创建了一个JUnit 测试 测试 有效的DAG图排序算法。 可以使用以下命令运行: java -cp .:junit.jar:hamcrest-core.jar org.junit.runner.JUnitCore DAGSortTest 这不会 测试 特定的输出,而是 测试 符合拓扑顺序的一般规则的输出,这是因为给定的DAG图有多个 正确 的拓扑顺序。 ( )。 当给出无效的输入边/图时,它确保DAGSort算法 正确 地引发 异常 。 这种方式比@Test(expected=ArrayIndexOutOfBoundsException.class)更好,如果是在调用arr.display(方法之前就已经抛出 异常 的话, 测试 结果就不是我们想要的了。ExpectedException还能够验证 异常 信息,如exception.expectMessage(“there is an exception!被认为是一种不好的做法:期待一般的Exception,RuntimeException甚至是Throwable。 private final int age; private final String name; public Person(int age, String name) throws IllegalAgeException { super(); if(age < 0) throw new IllegalAgeExce 检查抛出的 异常 有三种方式,它们各自都有优缺点:1.@Test(expected…)@Test注解有一个可选的参数,"expected"允许你设置一个Throwable的子类。在 测试 的方法前加入类似下面的句子即可验证方法抛出预期的 异常 :简单明了,这个 测试 有一点误差,因为 异常 会在方法的某个位置被抛出,但不一定在特定的某行。2.ExpectedException如果要使用JUnit框架中的ExpectedException类,需要声明ExpectedException 异常 。然后你可以使用更加简单的方式验证预期的异 how do you assert that a certain exception is thrown in junit-4 tests 在 JUnit4 单元 测试 中,我要怎样做才能 测试 出有特定的 异常 抛出?我能想到的就只有下面的方法: @Test public void testFooThrowsIndexOutOfBoundsException() { public class ExpectedExceptionsTest { @Rule public ExpectedException thrown = ExpectedException.none(); //@Rule 注解的 Expec... 本问题已经有最佳答案,请猛点这里访问。我需要编写一个JUnit 测试 用例,它将 测试 一个传递不同排列的函数,并得到相应的结果。成功的用例不返回任何内容,而失败的排列会抛出 异常 ( 异常 类型无关紧要)。例如。testAppleisSweetAndRed(水果,颜色,味道) 测试 会调用以下内容 -testAppleisSweetAndRed(orange,red,sweet)//throws exception... 你好啊,我是大阳。 本文我们将讨论JUnit5的断言功能。 JUnit 5 断言是使用 测试 的实际结果验证预期结果。所有JUnit Jupiter 断言都是org.junit.jupiter.Assertions类中的静态方法,方便使用。 有 异常 的断言将抛出一个AssertionFailedError或它的一个子类。 1 assertEquals() 和 assertNotEquals() Assertions.assertEquals()用于断言期望值和实际值相等。Assertions.assertEqua public static List<String> getFiles(String path) { if(null==path){ logger.error("传入路径不能为空!");