首页 文章

JUnit混淆:使用'extends TestCase'或'@Test'?

提问于
浏览
135

我发现JUnit的正确使用(或至少是文档)非常令人困惑 . 这个问题既是未来的参考,也是一个真实的问题 .

如果我理解正确,有两种主要的方法来创建和运行JUnit测试:

Approach A (JUnit 3-style): 创建一个扩展TestCase的类,并使用单词 test 启动测试方法 . 将类作为JUnit Test(在Eclipse中)运行时,将自动运行以 test 开头的所有方法 .

import junit.framework.TestCase;

public class DummyTestA extends TestCase {

    public void testSum() {
        int a = 5;
        int b = 10;
        int result = a + b;
        assertEquals(15, result);
    }
}

Approach B (JUnit 4-style): 创建一个'normal'类并在方法前加一个 @Test 注释 . 请注意,您不必使用单词 test 启动方法 .

import org.junit.*;
import static org.junit.Assert.*;

public class DummyTestB {

    @Test
    public void Sum() {
        int a = 5;
        int b = 10;
        int result = a + b;
        assertEquals(15, result);
    }
}

混合两者似乎不是一个好主意,请参阅例如this stackoverflow question

现在,我的问题:

  • What is the preferred approach ,或者你何时会使用一个而不是另一个?

  • 方法B允许通过扩展@Test注释来测试异常,如 @Test(expected = ArithmeticException.class) . But how do you test for exceptions when using approach A?

  • 使用方法A时,您可以在测试套件中对许多测试类进行分组,如下所示:

TestSuite suite = new TestSuite("All tests");
suite.addTestSuite(DummyTestA.class);
suite.addTestSuite(DummyTestAbis.class);

但这不能用于方法B(因为每个测试类应该是TestCase的子类) . What is the proper way to group tests for approach B?

编辑:我已经为这两种方法添加了JUnit版本

5 回答

  • 23

    我更喜欢JUnit 4(Annotation方法),因为我发现它更灵活 .

    如果要在JUnit 4中构建测试套件,则必须创建一个类,对所有测试进行分组,如下所示:

    import org.junit.runner.RunWith;
    import org.junit.runners.Suite;
    import org.junit.runners.Suite.SuiteClasses;
    
    
    @RunWith(Suite.class)
    @SuiteClasses({
        Test1.class,
        Test2.class,
        Test3.class,
        Test4.class
    })public class TestSuite
    {
     /* empty class */
    }
    
  • 4

    区别很简单:

    • 扩展 TestCase 是单元测试在JUnit 3中编写的方式(当然它在JUnit 4中仍然受支持)

    • 使用 @Test 注释是JUnit 4引入的方式

    通常,您应该选择注释路径,除非需要与JUnit 3(和/或Java 5之前的Java版本)兼容 . 新方法有几个优点:

    要在JUnit 3 TestCase 中测试预期的异常,您必须使文本显式化 .

    public void testMyException() {
      try {
        objectUnderTest.myMethod(EVIL_ARGUMENT);
        fail("myMethod did not throw an Exception!");
      } catch (MyException e) {
        // ok!
        // check for properties of exception here, if desired
      }
    }
    
  • 1

    您的问题有一个未解答的部分,那就是“对方法B进行分组测试的正确方法是什么?”

    官方答案是您使用@RunWith(Suite.class)注释类,然后使用@ Suite.SuiteClasses批注列出类 . 这就是JUnit开发人员如何做到这一点(手动列出套件中的每个类) . 在许多方面,这种方法是一种改进,因为在套件和套件后行为之前添加它是微不足道和直观的(只需将@BeforeClass和@AfterClass方法添加到使用@RunWith注释的类中 - 比旧的TestFixture更好) .

    但是,它确实有一个倒退,因为注释不允许您动态创建类列表,并且解决该问题会变得有点难看 . 您必须继承Suite类并在子类中动态创建类的数组并将其传递给Suite构造函数,但这是一个不完整的解决方案,因为Suite的其他子类(如Categories)不能与它一起使用不支持动态Test类集合 .

  • 104

    你应该使用JUnit 4.它更好 .

    许多框架已开始弃用JUnit 3.8支持 .

    这是来自Spring 3.0参考文档:

    [警告]不推荐使用旧版JUnit 3.8类层次结构

    通常,在开始新的操作时,应始终尝试使用框架的最新稳定版本 .

  • 15
    • “首选”方法是使用自Junit 4以来引入的注释 . 它们使很多事情变得更容易(请参阅第二个问题)

    • 您可以使用简单的try / catch块:

    public void testForException() {
        try {
            Integer.parseInt("just a string");
            fail("Exception should have been thrown");
        } catch (final Exception e) {
            // expected
        }
    }
    

相关问题