使用系统属性和静态字段迁移到 Maven 时出现 JUnit 类加载器问题
JUnit classloader issues when moving to Maven with System properties and static fields
我正在努力将我们的遗留构建从使用 Ant 转换为 Maven(3.3.3,如果重要的话),并且 运行 成为一个障碍。我们的代码库有一个 class 从系统属性初始化一个私有静态字段,通常由应用程序调用时的启动脚本填充。执行此代码的单元测试是在执行测试之前设置系统属性。当 运行 在 Ant 中或通过 Eclipse JUnit 运行程序进行单元测试时,一切正常。通过maven 运行 时,似乎在单元测试执行前就初始化了静态字段,导致属性不存在,测试失败。
我已经将示例 class 和单元测试放在一起进行演示,因为不允许我在此处 post 实际代码。
package foo.bar;
public class ValueClass {
private static final String SAMPLE_FIELD = "Foo " + System.getProperty("target.value");
private final myValueField;
public ValueClass() {
myValueField = "random text " + SAMPLE_FIELD;
}
public String getValueField() {
return myValueField;
}
}
以及对应的单元测试:
package foo.bar;
import org.junit.Test;
import org.junit.BeforeClass;
public class ValueClassTest {
@BeforeClass
public static void setupBeforeClasses() {
System.setProperty("target.value", "value from test");
}
@Test
public void testGetValueField() {
String expected = "random text Foo value from test";
ValuesClass valuesClassInstance = new ValuesClass();
String actual = valuesClassInstance.getValueField();
assertEquals(expected, actual);
}
}
正如我提到的,当我使用 Ant 或 Eclipse 执行时,一切正常。我玩过一些日志记录(将一些日志消息放入 ValueClass 的静态块中),并确定当 运行 在 Eclipse 或 Ant 中时,class 在 testGetValueField 方法执行期间加载,在 Maven 中,class 在执行 setupBeforeClasses 方法之前的某个时间加载。这会导致 SAMPLE_FIELD 使用 "target.value" 系统 属性.
中的空值进行初始化
非常感谢任何帮助!
罗布
如果您可以通过 pom.xml
设置系统属性,则停止使用 @BeforeClass
方法和 try this:
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<systemPropertyVariables>
<propertyName>propertyValue</propertyName>
<buildDirectory>${project.build.directory}</buildDirectory>
[...]
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
[...]
</project>
我正在努力将我们的遗留构建从使用 Ant 转换为 Maven(3.3.3,如果重要的话),并且 运行 成为一个障碍。我们的代码库有一个 class 从系统属性初始化一个私有静态字段,通常由应用程序调用时的启动脚本填充。执行此代码的单元测试是在执行测试之前设置系统属性。当 运行 在 Ant 中或通过 Eclipse JUnit 运行程序进行单元测试时,一切正常。通过maven 运行 时,似乎在单元测试执行前就初始化了静态字段,导致属性不存在,测试失败。
我已经将示例 class 和单元测试放在一起进行演示,因为不允许我在此处 post 实际代码。
package foo.bar;
public class ValueClass {
private static final String SAMPLE_FIELD = "Foo " + System.getProperty("target.value");
private final myValueField;
public ValueClass() {
myValueField = "random text " + SAMPLE_FIELD;
}
public String getValueField() {
return myValueField;
}
}
以及对应的单元测试:
package foo.bar;
import org.junit.Test;
import org.junit.BeforeClass;
public class ValueClassTest {
@BeforeClass
public static void setupBeforeClasses() {
System.setProperty("target.value", "value from test");
}
@Test
public void testGetValueField() {
String expected = "random text Foo value from test";
ValuesClass valuesClassInstance = new ValuesClass();
String actual = valuesClassInstance.getValueField();
assertEquals(expected, actual);
}
}
正如我提到的,当我使用 Ant 或 Eclipse 执行时,一切正常。我玩过一些日志记录(将一些日志消息放入 ValueClass 的静态块中),并确定当 运行 在 Eclipse 或 Ant 中时,class 在 testGetValueField 方法执行期间加载,在 Maven 中,class 在执行 setupBeforeClasses 方法之前的某个时间加载。这会导致 SAMPLE_FIELD 使用 "target.value" 系统 属性.
中的空值进行初始化非常感谢任何帮助! 罗布
如果您可以通过 pom.xml
设置系统属性,则停止使用 @BeforeClass
方法和 try this:
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<systemPropertyVariables>
<propertyName>propertyValue</propertyName>
<buildDirectory>${project.build.directory}</buildDirectory>
[...]
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
[...]
</project>