如何在任何类中的任何测试之前和之后运行一组代码?

时间:2014-10-13 14:52:57

标签: java unit-testing junit initialization

这是我的测试代码:

public class Test1 {
    @BeforeClass
    public void setUp() {
        EmbeddedTomcat.start();
    }

    // test methods...

    @AfterClass
    public void tearDown() {
        EmbeddedTomcat.stop();
    }      
}

public class Test2 {
    @BeforeClass
    public void setUp() {
        EmbeddedTomcat.start();
    }

    // test methods...

    @AfterClass
    public void tearDown() {
        EmbeddedTomcat.stop();
    }
}

// ...

如您所见,我在每个Test类中复制了对嵌入式tomcat的启动和停止调用。如何避免与JUnit重复?

要求:     - 对于所有测试类,必须为ONCE调用start和stop调用

JUnit 4.11

2 个答案:

答案 0 :(得分:3)

除了创建一个运行@BeforeClass@AfterClass的父类。你可以创建一个JUnit Rule。您可以创建规则子类ExternalResource,其中包含在执行(类或测试)之前和之后添加行为的方法。

public class EmbeddedTomcatServer extends ExternalResource {

            ...

            @Override
            protected void before() throws Throwable {
                    EmbeddedTomcat.start();
            };

            @Override
            protected void after() {
                    EmbeddedTomcat.stop();
            };
    }

然后在您的测试中使用在@ClassRulebefore()时间内运行服务器的after()BeforeClass方法的AfterClass

public class Test1 {

   @ClassRule
   public static EmbeddedTomcatServer tomcat = new EmbeddedTomcatServer();

   //tests as normal, no more @BeforeClass or @AfterClass

}

public class Test2 {

   @ClassRule
   public static EmbeddedTomcatServer tomcat = new EmbeddedTomcatServer();

   //tests as normal, no more @BeforeClass or @AfterClass

}

此解决方案可能比使用父类更好,因为您可以在任何测试中使用此规则而无需更改父类。

修改 只运行start()和stop()一次

有点不清楚你是说每个测试类运行一次启动和停止(使用@BeforeClass和@AfterClass作为原始代码)

或者,如果您希望在运行的所有测试类中的所有测试中仅运行一次启动和停止。

如果你想做后者,@ ClassRules也很有帮助。只需创建一个包含要使用的测试类的测试套件,然后将ClassRule仅放在套件类中

@RunWith(Suite.class)
@SuiteClasses({ Test1.class, Test2.class })
public class AllTests {
   @ClassRule
   public static EmbeddedTomcatServer tomcat = new EmbeddedTomcatServer();

}

这将在AllTests套件启动时启动tomcat,然后在测试套件中的所有测试运行时停止tomcat。

答案 1 :(得分:2)

如果您的项目可能,您可以创建一个TestParent类来定义这些@BeforeClass@AfterClass方法,并使您的Test1Test2类扩展从它。

public class TestParent {
    @BeforeClass
    public void setUp() {
        EmbeddedTomcat.start();
    }

    @AfterClass
    public void tearDown() {
        EmbeddedTomcat.stop();
    }    
}

public class Test1 extends TestParent {
    //...
}

public class Test2 extends TestParent {
    //...
}