Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 354|回复: 0

[Java框架学习]JUnit 4快速入门

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-29 23:58:28 | 显示全部楼层 |阅读模式
    JUnit 4是JUnit框架有史以来的最大改进,其主要目标便是利用java 5的Annotation特性简化测试用例的编写。让我们看看如何使用JUnit 4来进行Unit测试。      请注意:本文主要介绍JUnit 4的最新特性和用法,并不会讲解Unit测试的基础。如果你对JUnit框架还不熟悉,请先参考“在Eclipse中使用JUnit”一文,学习如何编写JUnit测试。 我们使用的开发环境是Eclipse 3.2,它已经自带了JUnit 4.1,你需要将JUnit 4 Library添加到项目用到的Library中。另外,必须使用JDK 5.0或更高版本。 要在Eclipse环境之外运行JUnit,需要下载JUnit 4.1,具体请访问JUnit.org。 我们先看一个简单的Math类:

       
      
      
       
       
       
         package
          com.crackj2ee.junit4;
    public class
          Math {

         public int abs(int
          value) {
             return value>=0 ? value : (-
         value);
         }

         public int div(int a, int
          b) {
             return a /
          b;
         }

         /**
         
          * BUG: if b less than 0!
          
         */
         
         
         public float exp(int a, int
          b) {
             float r = 1
         ;
             for(int i=0; i<b; i++
         )
                 r = r *
          a;
             return
          r;
         }
    }
         
        注意exp()方法是有Bug的,如果传入参数2, -1,则期待的返回值应为0.5F,但实际返回值为1.0F。 下面我们看看传统的JUnit的TestCase:
       
       
         public class MathTest extends
          TestCase {

         public void setUp() { super
         .setUp(); }
         public void tearDown() { super
         .tearDown(); }

         public void testAbs() { assertTrue(true
         ); }
         public void
          testDiv() {...}
         public void
          testExp() {...}

    }
         
        JUnit依赖反射来执行每个以test开头的方法。然而,在最新的JUnit 4中,由于有了Annotation的支持,我们的测试方法不需要再以testXxx标识了,而是写上一个@Test标注即可。例如:
       
       
         @Test public void doAbs() {...}
         
        甚至MathTest类也不必继承自TestCase。你也许会想到,不继承自TestCase就无法调用assertXxx方法了,正因为如此,所有的assertXxx方法全部以静态方法被放入了Assert类,使用Assert.assertXxx()调用。如果使用
       
       
         import static org.junit.Assert.*;
         
        则原有的代码不必改动。 setUp()和tearDown()方法也依赖@Before和@After标记,这样做的最大的好处是在继承体系内不必担心忘记了在setUp()方法中调用父类的super.setUp()方法,JUnit框架会自动处理父类的@Before和@After标记的方法。 并且,JUnit框架对@Before和@After的调用顺序类似于类的构造方法和析构方法,即@Before按照父类到子类的顺序调用,@After则相反,这样保证了资源的正确获取和释放。 当然,不再强迫必须使用setUp和tearDown作为方法名,可以使用更有意义的方法名,例如:initDatabase()和closeDatabase(),只要它们被标注了@Before和@After即可。 来看看使用Annotation的MathTest:
       
       
         package
          com.crackj2ee.junit4;

    import static org.junit.Assert.*
         ;

    import org.junit.*
         ;

    public class
          MathTest {

         public
          MathTest() {
             System.out.println("new MathTest instance."
         );
         }

         @Before
         public void setUp() throws
          Exception {
             System.out.println("call @Before before a test method"
         );
         }

         @After
         public void tearDown() throws
          Exception {
             System.out.println("call @After after a test method"
         );
         }

         @Test
         public void
          doAbs() {
             Math math = new
          Math();
             assertEquals(200, math.abs(200
         ));
             assertEquals(100, math.abs(-100
         ));
             assertEquals(0, math.abs(0
         ));
         }

         @Test
         public void
          doDiv() {
             Math math = new
          Math();
             assertEquals(5, math.div(100, 20
         ));
             assertEquals(4, math.div(100, 21
         ));
         }

         @Test(expected=ArithmeticException.class
         )
         public void
          doDiv0() {
             new Math().div(127, 0
         );
         }

         @Test(timeout=1
         )
         public void
          doLongTimeTask() {
             double d = 0
         ;
             for(int i=1; i<10000000; i++
         )
                 d+=
         i;
         }

         @Test
         public void
          testExp() {
             Math math = new
          Math();
             assertEquals(32f, math.exp(2, 5), 0.001f
         );
             assertEquals(1f, math.exp(2, 0), 0.001f
         );
             assertEquals(0.5f, math.exp(2, (-1)), 0.001f
         );
         }

    }
         
        对测试异常,JUnit 4可以用expected=Exception.class来期待一个预期的异常,而不必编写
       
       
         try
          {
       ...
       fail("No exception"
         );
    }
    catch
         (Exception e) {
       // OK!
         

         }
         
        来看看doDiv0测试,我们期待一个除数为0的ArithmeticException,因此编写如下测试方法:
       
       
         @Test(expected=ArithmeticException.class
         )
    public void
          doDiv0() {
         new Math().div(127, 0
         );
    }
         
        对于非常耗时的测试,@Test还有一个timeout来标识该方法最长执行时间,超过此时间即表示该测试方法失败:
       
       
         @Test(timeout=1
         )
    public void
          doLongTimeTask() {
         double d = 0
         ;
         for(int i=1; i<10000000; i++
         )
             d+=
         i;
    }
         
        以上方法若执行时间超过1ms则测试失败,由于依赖CPU的执行速度,在不同的机器上测试结果也不同。 JUnit 4另一个较大的变化是引入了@BeforeClass和@AfterClass,它们在一个Test类的所有测试方法执行前后各执行一次。这是为了能在@BeforeClass中初始化一些昂贵的资源,例如数据库连接,然后执行所有的测试方法,最后在@AfterClass中释放资源。 正如你能想到的,由于@BeforeClass和@AfterClass仅执行一次,因此它们只能标记静态方法,在所有测试方法中共享的资源也必须是静态引用:
       
       
         private static
          Object dbConnection;

    @BeforeClass
    public static void setUpBeforeClass() throws
          Exception {
         System.out.println("call @BeforeClass and init database connection"
         );
         dbConnection = new
          Object();
    }

    @AfterClass
    public static void tearDownAfterClass() throws
          Exception {
         System.out.println("call @AfterClass to release database connection"
         );
         dbConnection = null
         ;
    }
         
        最后执行测试用例,可以看到结果: 各个方法执行顺序如下: call @BeforeClass and init database connection

    new MathTest instance.
    call @Before before a test method
    call @After after a test method

    new MathTest instance.
    call @Before before a test method
    call @After after a test method

    ...

    call @AfterClass to release database connection 可以看到,@BeforeClass是在实例化MathTest之前调用的,因此不能在构造方法中初始化共享资源。 最后需要注意的是由于Java 5的自动Box/Unbox特性,在调用assertEquals()时要特别注意,如果你传入: assertEquals(100F, 100); 则按照自动Box变为: assertEquals(new Float(100F), new Integer(100)); 测试失败,因为Float类和Integer类不是同一类型。 因此要特别注意float和double的测试。事实上对float和double应使用 assertEquals(float, float, float delta);
    assertEquals(double, double, double delta); delta指定了两个作比较的浮点数的相差范围,在此范围内的两个浮点数将认为相等。可以传入一个很小的数例如0.0001F。  JUnit 4非常适合使用Java 5的开发人员,但是无法在Java 1.4中获得这些好处,并且,也不与以前的版本兼容。因此,如果你正在使用Java 5,就可以考虑使用JUnit 4来编写测试。 下载本文完整的源代码和Eclipse工程
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-5 12:03 , Processed in 0.357008 second(s), 38 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表