`
endual
  • 浏览: 3542070 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

junit 测试异常(转)

    博客分类:
  • java
 
阅读更多

  今天做单元测试,要求做下路径覆盖,于是乎要对异常进行测试了。这个第一次搞,

不知道怎么下手,当遇到异常,马上终止测试(测试没有通过),但是不在catch中写的话,有不符合要求,于是网上转了下。算是解决了。

 

测试是否抛出正确的异常(Test throwing the right exception)

博客分类:
问题: 
    你是否想过异常也要去测试?你想了怎么验证一个方法是否在某种特定的情况下抛出期望的异常,也许你正在找是否要测试,以及有没有简单的测试方法 

背景: 
    要想知道任何实现这种测试,你需要了解JUnit如何判定一个测试时通过还是失败。如果一个断言失败或者抛出一个异常的时候,测试就会失败,否则测试就通过。换句话说,如果一个测试全部走完,就是说程序从头运行到了尾,而没有从中间跳过,那么它就通过了。知道了这些,就足够你推断出然后写这种测试了:如果该抛出异常的代码段没有抛出异常,那么这个测试就应该失败;测试只能捕捉期望的异常;任何其他的异常都应该由JUnit框架捕捉。 

诀窍: 
   下面的代码展示了,如何写这种验证是否抛出正确异常的测试示例: 
Java代码  收藏代码
  1. public void testConstructorDiesWithNull() throws Exception{  
  2.   try{  
  3.       Fraction oneOverZero = new Fraction(1,0);  
  4.       fail("Created fraction 1/0! That's undefined!");  
  5.     }  
  6.  catch(IllegalArgumentException excepted){  
  7.      assertEquals("denominator",excepted.getMessage());  
  8.       }  
  9. }  

首先分析上面的代码 
1. 找到可能抛出异常的代码段,将它放入一个try语句内。 
2. 调用了应该抛出异常的方法以后,在try语句内写一个fail()方法来说明:“如果运行到了这里,那么说明期望的异常没有被抛出”。 
3. 添加一个catch语句以捕获期望的异常。 
4. 在catch语句内,如果需要的话,验证捕获的异常的属性与你期望的相同。 
5. 声明该测试方法会抛出异常,这可以让代码适应性更强。有人可能会在测试程序外声明这个方法可抛出其他的异常,这种变化不应该影响你的测试,因此它不应该导致你的测试不能被编译。 

讨论: 
如果测试的方法抛出其他的异常---------不同于你要捕获的异常-----那么JUnit将报告一个error,而不是failure,因为测试方法将一个异常抛出给JUnit框架。记住这样的error一般是环境或者测试程序自身的错误,而不是产品代码的问题。如果产品代码抛出了一个预期之外的异常,那么一般可能是潜在的问题阻碍了测试的正常运行。 

一个更面向对象的解决办法 
先看一个匿名内部类 
Java代码  收藏代码
  1. public void testForException(){  
  2.   assertThrows(MyException.classnew ExceptionClosure(){  
  3.      public Object execute(Object input) throws Exception{  
  4.           return doSomethingThatShouldThrowMyException();  
  5.          }  
  6.     });  
  7.   }  

虽然有人觉得Java的匿名内部类不太好读,但这个方法的意图再明显不过了:"测试这段代码是否抛出期望的异常"。可以按如下的方式实现assertThrows()方法: 
Java代码  收藏代码
  1.   public static void assertThrows(Class expectedExceptionClass, ExceptionalClosure closure){  
  2.     String expectedExceptionClassName = expectedExceptionClass.getName();  
  3.   
  4.  try{  
  5.        closure.execute(null);  
  6.        fail("Block did not throw an exception of type"+expectedExceptionClassName);  
  7.      }  
  8. catch(Exception e){  
  9.    assertTrue("Caught exception of type <" + e.getClass().getName()  
  10.               +">, expected one of type <"  
  11.               +expectedExceptionClassName+">",  
  12.               expectedExceptionClass.isInstance(e));  
  13. }  
  14. }  

我们捕捉了所有的异常,而不仅是期望的异常,这是因为当编译的时候,我们还不知道代码会抛出什么样的异常。如果这样设置断言,那么错误信息就很重要,因为你取走了错误信息的控制权。另外一个可选的方案是,在assertThrows()方法中添加另外一个参数,用来接收自定义的异常,最后,因为我们必须测试所有的异常,我们必须将捕获的异常是否是期望的异常的实例,这与使用instanceof()方法是一样的。 

注意写的断言: 
如果你的断言与特定的异常相关,那么你要小心:如果验证异常对象的结构过于紧凑,那么可能导致测试与产品代码耦合得过强。这时候,测试的结果可能有点不太可靠。假设异常信息是给终端用户看,而你要写直接验证该消息的断言。一般来说,你会照着如下的方式编写测试代码: 
Java代码  收藏代码
  1. public void testNameNoEntered(){  
  2.  try{  
  3.      log("""password");  
  4.      fail("User logged in without a user name !");  
  5.      }  
  6. atch(MissingEntryException expected){  
  7.     assertEquals("userName", expected.getEnteryName());  
  8.     assertEquals("Please enter a user name and try again",  
  9.   expected.getMessage());  
  10.   
  11.      }  
  12. }  

测试代码看上去很清楚:如果一个用户不输入用户名的情况下登录,那么登录模块就抛出一个MissingEntryException。这个异常包含了登录所缺少的必要项的名称,以及提供给终端用户的信息。这看起来很好,因为这个异常对象包含的信息非常简单,它包含的数据像终端用户读取的信息一样易于理解。虽然catch语句中的第一断言写得不错,但是第二个有点不同的意见,虽然userName是程序的内部名称,并且是行为的一部分,但给终端用户看的信息可以在不影响登录功能的前提下随时改变。换句话说,如果userName改变的话,测试程序就需要随之改变。然而,测试似乎不应该随着终端用户信息的改变而改变,由于测试时现在写的,将来任何属性值的改变,都会要求测试程序随之改变。 

这个例子中,我们建议去除第二个断言而仅保留第一个,因为涉及的一般准则是:将给终端用户看的信息与内部对象的行为相分离。你可以经常简单地初始化应该异常对象,然后检查它的toString()以及getMessage()方法的返回值。
分享到:
评论

相关推荐

    自动饮料机Junit测试(软件测试与质量保证实验).rar

    3. **异常处理**:测试异常处理逻辑,确保在出现错误时程序行为符合预期。 4. **正向测试**:验证正常输入和操作的正确性。 5. **负向测试**:验证程序对错误输入和非法操作的响应。 **自动饮料机案例** 在这个...

    junit测试_java_JUnit_JUnit测试_

    例如,文件可能会讲解如何设置一个基本的JUnit测试类,通常这个类会继承自`junit.framework.TestCase`(对于较旧的JUnit版本)或者使用注解`@RunWith(JUnit4.class)`(对于JUnit 4及以上版本)。 测试类中的每个...

    Junit测试jar包

    JUnit测试jar包通常包含了JUnit框架的核心库和其他可能的扩展或辅助库,使得开发人员可以在他们的项目中引入这些测试工具。这个压缩包很可能包含了JUnit的不同版本,例如JUnit4或JUnit5,以及可能的依赖如Hamcrest...

    JUnit和单元测试入门简介

    * JUnit Framework 中的出错异常(AssertionFailedError)。 JUnit 安装步骤包括: 1. 下载 JUnit 包并将 Junit 压缩包解压到一个物理目录中。 2. 记录 Junit.jar 文件所在目录名。 3. 配置环境变量。 JUnit 中...

    JUnit测试代码示例

    5. **异常测试**:JUnit3允许你测试一个方法是否抛出了预期的异常,例如`try { ... } catch (Exception e) { fail("异常未正确抛出"); }` 6. **测试运行器**:JUnit3默认的运行器会顺序执行所有的测试,如果有测试...

    Junit测试学习文档

    《Junit测试学习文档》 在软件开发过程中,单元测试是一项至关重要的工作,它能确保代码的正确性,提高代码质量,并为后续的维护和重构提供保障。Junit作为Java编程语言中最流行的单元测试框架,是每个Java开发者...

    javaweb中.java文件测试需要的框架(junit测试).rar

    本压缩包文件"javaweb中.java文件测试需要的框架(junit测试).rar"显然是为了帮助开发者理解如何在Java Web项目中使用JUnit进行测试。 **JUnit框架详解** JUnit是一个基于注解的测试框架,它的核心功能包括: 1....

    junit测试案例程序

    在这个“junit测试案例程序”中,我们可以找到一些基本的JUnit测试用例示例,这对于初学者来说是极好的学习资源。 首先,JUnit的核心概念是测试类和测试方法。一个测试类通常对应于被测试的业务逻辑类,而测试方法...

    junit测试测试代码

    下面将详细阐述JUnit测试的相关知识点。 1. **JUnit简介**: JUnit是由Ernst von Reiss和Kent Beck开发的一个开源项目,它是XUnit测试框架家族的一员,专为Java设计。JUnit提供了注解、断言、测试套件、定时器等...

    junit测试小例子

    `@Expected`注解可以指定测试方法预期抛出的异常类型,如果方法没有抛出预期的异常或者抛出了不同类型的异常,测试就会失败。 JUnit还支持断言(Assertions),这是测试的核心部分。通过使用如`assertEquals`、`...

    junit测试小demo

    在这个名为"junit测试小demo"的压缩包文件中,我们可以预期它包含了一些关于如何使用Junit进行单元测试的示例代码或教程。 首先,让我们来理解一下Junit的基本概念。Junit是一个开源项目,由Eclipse基金会维护,...

    junit4测试jar包

    3. **异常测试**:`@Test(expected = Exception.class)`可以用来测试方法是否抛出了预期的异常。 4. **测试套件(Test Suites)**:`@Suite`注解允许将多个测试类组合成一个测试套件,便于一起运行。 5. **参数化...

    在Eclipse中使用JUnit4进行单元测试

    创建JUnit测试类是单元测试的第一步。在Eclipse中,右键点击项目,选择"New" &gt; "JUnit Test Case"。在此过程中,需要选择要测试的源代码类以及要测试的方法。测试类通常会继承自`org.junit.Test`注解的基类,并且每...

    Java单元测试JUnit4.7

    在实际使用中,开发人员通常会结合构建工具如Maven或Gradle,以及IDE如Eclipse、IntelliJ IDEA来运行JUnit测试。这些工具能够自动化测试执行,生成测试报告,帮助分析和调试。 总的来说,JUnit 4.7作为Java单元测试...

    junit测试工具以及安装方法

    本文将详细介绍JUnit测试工具及其安装方法。 **一、JUnit简介** JUnit是一个开源的、基于Java的测试框架,主要用于编写和运行可重复的单元测试。它的设计理念是使测试成为开发过程中的一个自然部分,通过自动化测试...

    生成junit测试类

    这篇博文“生成junit测试类”可能讲述了如何使用特定工具或方法来自动化创建JUnit测试类的过程。下面将详细讨论JUnit测试、EasyMock和PowerMock等相关知识点。 1. JUnit测试:JUnit是Java编程语言的一个开源测试...

    junit4测试源码

    异常测试也是JUnit4的一个重要特性,可以使用`assertThrows()`来断言预期的异常是否被抛出。例如,`assertThatThrownBy(() -&gt; someCode()).isInstanceOf(ExpectedException.class)`。 JUnit4还引入了`Assume`类,...

    junit单元测试junit单元测试junit单元测试

    为了提高测试覆盖率,开发者应尽可能覆盖所有可能的代码路径,包括正常情况、边界情况和异常处理。JUnit也支持参数化测试,通过`@ParameterizedTest`注解可以运行同一测试逻辑但使用不同参数的测试用例。 此外,...

    JUnit_Test_Code.zip_JUnit_JUnit测试_junit测试脚本

    本资源"JUnit_Test_Code.zip"包含了一份关于如何使用JUnit进行测试的实例,以及图文并茂的讲解,对于理解和实践JUnit测试脚本非常有帮助。 在Java开发中,单元测试是对软件中的最小可测试单元进行检查和验证的过程...

    junit测试.zip

    这个“junit测试.zip”文件包含了JUnit库的jar包,它用于帮助进行程序的单元测试。单元测试是对软件中的最小可测试单元进行检查和验证,通常是一个方法或一个类。 在Java开发中,单元测试是质量保证的关键步骤,...

Global site tag (gtag.js) - Google Analytics