我发现执行多个JUnit测试时静态块只运行一次。 如何强制它为每个测试方法运行?我正在使用最新的JUnit 4.8.2
另外,根据xUnit设计原则,每种方法都应该完全独立于其他方法。为什么静态块只能执行一次?
@Test TestMethod1 () {
Accounts ac = new Accounts();
ac.method1(); //kill the thread inside
}
@Test TestMethod2 () {
Accounts ac = new Accounts();
ac.method2(); // the thread is no longer available!!
}
class Accounts {
static {
// initalize one thread to monitor something
}
}
当 TestMethod1 和 TestMethod2 位于不同的测试类中时,甚至会发生这种情况。
答案 0 :(得分:10)
静态块仅在类加载时执行,因为它们就是这样的:类初始化器。要让多次运行静态块,需要卸载该类(这不是一件容易的事情......)。
如果您需要使用静态块,您可以想出测试它们的方法。为什么不将块解包为公共(静态)方法?你在这个世界所要做的就是测试方法:
static {
staticInitMethod();
}
public static void staticInitMethod(){
//insert initialization code here
}
您也可以使用普通的初始化程序
{//not static
//insert initialization code here
}
尽管如此,事实是大多数代码都不需要像这样使用初始化器。
编辑:结果Oracle喜欢静态方法方法http://download.oracle.com/javase/tutorial/java/javaOO/initial.html
答案 1 :(得分:4)
为什么静态块只能执行一次?
因为这是静态初始化程序块的重点!
或者换句话说,如果你想要一些初始化代码执行多次,把它放在一个常规的构造函数或方法中,或者(在极少数情况下)一个非静态初始化器块。
在JUnit的上下文中,使用setUp()
和tearDown()
方法实现测试启动和关闭代码的常规方法。
如果您正在尝试在自己的代码中对静态初始化的执行进行单元测试,那么我认为您处于一条艰难的道路上。但是,对具有静态状态(例如单例)的代码进行单元测试总是很困难......而这也是人们认为静态是一个坏主意的原因之一。
考虑使用依赖注入(又名反转控制)框架而不是单例。
或者,考虑修改单例/静态初始化代码以使其更容易测试。例如,添加一个允许测试重新执行初始化的静态方法。 (在你说这打破单身模式之前:是的,我知道。你需要在设计/实施“纯度”和易于测试之间做出选择。)
答案 2 :(得分:0)
正在测试的类的测试的静态代码是什么?
如果代码是静态的,那么测试可以共享,那么您需要将代码移动到自己的类中。然后要么让测试类构造函数实例化一个静态实例,要么创建一个执行相同操作的测试套件。
如果您希望每个测试都独立,那么将您在静态块中执行的操作移动到setup()/ teardown()方法中,这就是它们的用途。
答案 3 :(得分:0)
当第一次将类加载到JVM中时,静态块仅执行一次。 Junit提供@Before
批注,该批注基本上用于测试用例的必需初始化。这可以用于执行类的静态块。例如,我有以下课程Car
public class Car implements Vehicle{
private String type = "lmv";
static {
VehicleFactoryWithoutRefl.getInstance().registerVehicle("car", new Car());
}
@Override
public void moveForward() {
}
@Override
public String getType() {
return type;
}
@Override
public Vehicle createVehicle() {
return new Car();
}
}
,我想在创建汽车实例之前在Junit中执行此类的静态块。我必须使用setUp()
Junit代码在class.forName("package.ClassName")
中加载此类。
public class TestFactory {
@Before
public void setUp() {
try {
Class.forName("com.cg.dp.factory.Car");
} catch (ClassNotFoundException e) {
//e.printStackTrace();
}
}
@Test
//@Ignore
public void testFactoryInstanceWithoutRefl() {
Vehicle v1 = VehicleFactoryWithoutRefl.getInstance().newVehicle("car");
assertTrue(v1 instanceof Car);
}
}
答案 4 :(得分:-3)
嗯......让它非静态?您也可以拥有实例初始化程序块(与静态块相同,只是没有static
关键字)。但是,测试设置代码实际上应该采用明确的setUp()
或@Before
方法。