Java 测试类中的Junit参数化设置常量
我试图运行一个参数化junit测试,其中参数在测试中必须是常量,所以我使用反射来设置该参数。然而,它并不完全有效。在下面的示例中,它总是打印Java 测试类中的Junit参数化设置常量,java,junit,Java,Junit,我试图运行一个参数化junit测试,其中参数在测试中必须是常量,所以我使用反射来设置该参数。然而,它并不完全有效。在下面的示例中,它总是打印测试:param-1。我如何解决这个问题?令人惊讶的是,我在调试器中为不同运行实例的PARAM_NAME(PARAM-1、PARAM-2、PARAM-2)获得了正确的值,但它在控制台中始终打印为“PARAM-1”,在测试中也用作“PARAM-1”。这可以部分解释为注释是在编译时计算的,所以注释中的值在运行时不能更改 @RunWith(Parameterize
测试:param-1
。我如何解决这个问题?令人惊讶的是,我在调试器中为不同运行实例的PARAM_NAME(PARAM-1、PARAM-2、PARAM-2)获得了正确的值,但它在控制台中始终打印为“PARAM-1”,在测试中也用作“PARAM-1”。这可以部分解释为注释是在编译时计算的,所以注释中的值在运行时不能更改
@RunWith(Parameterized.class)
public class SomeTest {
private final String PARAM_NAME = "param-1";
public SomeTest(String someParam){
org.springframework.test.util.ReflectionTestUtils.setField(this, "PARAM_NAME", someParam);
}
@Parameterized.Parameters
public static Collection parameters() {
return Arrays.asList(new Object[][] {
{ "param-1" },
{ "param-2" },
{ "param-3" }
});
}
@Test
@ExternalAnnotation(PARAM_NAME) //needs constant in annotation
public void testSomething() throws Exception {
System.out.println("Testing with: "+PARAM_NAME); //always prints param-1
//some tests
}
}
注释值由JVM缓存,在运行时无法更改。我能想到的唯一可能的方法是,通过源代码生成(基于模板,或使用类似库)以编程方式生成测试类。如果您在测试编译之前的生命周期阶段这样做(假设您使用的是Maven或Gradle之类的构建系统),那么您应该可以相对轻松地启动和运行。注释值由JVM缓存,您无法在运行时更改它。我能想到的唯一可能的方法是,通过源代码生成(基于模板,或使用类似库)以编程方式生成测试类。如果您在测试编译之前的生命周期阶段这样做(假设您使用的是Maven或Gradle之类的构建系统),那么您应该可以相对轻松地启动和运行。我可以通过在运行时更改注释值来做到这一点:
public static void changeAnnotationValue(Annotation annotation, String key, Object newValue) throws NoSuchFieldException, IllegalAccessException {
Object handler = Proxy.getInvocationHandler(annotation);
Field f = handler.getClass().getDeclaredField("memberValues");
f.setAccessible(true);
Map<String, Object> memberValues = (Map<String, Object>) f.get(handler);
memberValues.put(key,newValue);
}
虽然在主代码中这样做是完全不可取的,但可能会有副作用。我只是在测试类中执行此操作。我可以通过在运行时更改注释值来执行此操作:
public static void changeAnnotationValue(Annotation annotation, String key, Object newValue) throws NoSuchFieldException, IllegalAccessException {
Object handler = Proxy.getInvocationHandler(annotation);
Field f = handler.getClass().getDeclaredField("memberValues");
f.setAccessible(true);
Map<String, Object> memberValues = (Map<String, Object>) f.get(handler);
memberValues.put(key,newValue);
}
虽然在主代码中这样做是完全不可取的,但可能会有副作用。我只是在测试课上做的