我试图找到一种方法来正确实现测试类的设置和拆卸方法(与JUnit 4配合使用)。
尝试了很多事情并重新研究之后,我发现了这一点。
Difference between setUp() and setUpBeforeClass()
所以...如果是真的...我发现这种设计非常不灵活。
我的意思是...就我而言,我想为整个测试类运行一次@BeforeClass方法,即在所有测试用例方法之前运行一次,但要在我的测试类实例初始化之后运行一次。我需要将此方法作为实例方法。
似乎我做不到。它要求我将@BeforeClass方法定义为静态。
如果我尝试使用@Before实例方法,我可以看到它在每个测试用例方法之前被调用了很多次。但是我只需要调用一次。
有什么体面的方式可以做我想要的吗?我很惊讶...
这是有趣的部分:对于@Before OK ...,我可以做一些解决方法,可以定义一些布尔标志,然后检测到当前调用是第一个@Before方法调用。然后才做一些有用/实际的事情。
但是对于@After,我想检测@After方法的最后一次调用(这样,只有在最后一次调用时,我才在其中进行实际操作)。但是我无法使用任何标志检测到此最后一次调用。
我不知道JUnit的设计者怎么会想到所有这些。
或者...我想念什么吗?
答案 0 :(得分:0)
JUnit 4要求@BeforeClass
和@AfterClass
仅出现在static
方法中。如果您无法将方法static
设为模仿的最简单方法,那就是将静态持有人与@After
配合使用:
private static MyTest lastTest;
public cleanup() {
// actual instance cleanup
}
@After
public tearDown() {
lastTest = this;
}
@AfterClass
public static cleanup() {
if (lastTest != null) {
lastTest.cleanup();
}
}
这是一个丑陋的骇客,在某些情况下可能无法使用,并且可能会破坏与自定义运行程序的交互,例如SpringRunner
。在简单的情况下可能会起作用。
要回答为什么在此用例中JUnit 4和JUnit 5都不支持非静态方法的原因,请参见this comment:
在没有“每个测试类的测试实例”语义的情况下,要求@BeforeAll和@AfterAll方法是静态的。有关详细信息,请参见#48的说明。
但是,一旦解决了#48,对于可能有意义的情况,静态限制可能会被删除。
答案 1 :(得分:0)
您可以使用JUnit5(即Jupiter JUnit)完成所有这些操作。如果您确实需要使用JUnit4,则可能需要执行以下操作:
package com.jesperancinha.unittests;
import junit.extensions.TestSetup;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
public class OneTimeSetupUnitTest extends TestCase {
private static int up = 0;
private static int down = 0;
public static Test suite() {
return new TestSetup(new TestSuite(OneTimeSetupUnitTest.class)) {
protected void setUp() {
System.out.println("testStart");
up++;
System.out.println(up);
}
protected void tearDown() {
System.out.println("testEnd");
down++;
System.out.println(down);
}
};
}
@org.junit.Test
public void test1() {
System.out.println("test1");
System.out.println(up);
System.out.println(down);
}
@org.junit.Test
public void test2() {
System.out.println("test2");
System.out.println(up);
System.out.println(down);
}
}
这样做的好处是,您不会做任何意外的事情,包括适合您的情况。
如果运行此代码片段,您应该会得到类似以下内容的信息:
我已放置标志,以便向您显示一些跟踪信息以准确解释发生了什么。如您所见,标志“ up”在单元测试开始时立即更新。对于单个测试,它不会更改。直到测试结束,标志“ down”保持为0。仅在最后,此标志会更新。这意味着setUp仅被调用一次,而tearDown也仅被调用一次。您不需要同时使用这两种方法,因此我认为这就是您想要的。