這裏是一個小例子,其中使用靜態初始化一個工具類重新加載到該實用程序的測試初始化。 該實用程序使用系統屬性來初始化靜態最終值。通常這個值不能在運行時改變。 所以了JUnit測試重新加載類重新運行靜態初始化...
效用:
public class Util {
private static final String VALUE;
static {
String value = System.getProperty("value");
if (value != null) {
VALUE = value;
} else {
VALUE = "default";
}
}
public static String getValue() {
return VALUE;
}
}
了JUnit測試:
import static org.junit.Assert.assertEquals;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.junit.Test;
public class UtilTest {
private class MyClassLoader extends ClassLoader {
public Class<?> load() throws IOException {
InputStream is = MyClassLoader.class.getResourceAsStream("/Util.class");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int b = -1;
while ((b = is.read()) > -1) {
baos.write(b);
}
return super.defineClass("Util", baos.toByteArray(), 0, baos.size());
}
}
@Test
public void testGetValue() {
assertEquals("default", getValue());
System.setProperty("value", "abc");
assertEquals("abc", getValue());
}
private String getValue() {
try {
MyClassLoader myClassLoader = new MyClassLoader();
Class<?> clazz = myClassLoader.load();
Method method = clazz.getMethod("getValue");
Object result = method.invoke(clazz);
return (String) result;
} catch (IOException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
throw new IllegalStateException("Error at 'getValue': " + e.getLocalizedMessage(), e);
}
}
}
目前還不清楚你在問什麼。你是否正在尋找一個JUnit特性來在特定的時間運行代碼(何時?),或者你是否在初始化時是否可以修改外部'Foo'類? – chrylis
當然,您可以修改Foo以使其可變,但您明顯禁止這樣做。唯一的其他選擇是使用私有類加載器和反射來允許類重新加載。但是'Foo.getBar()'調用將不得不被重寫。 –
[Java:如何「重新啓動」一個靜態類的可能的重複?](http://stackoverflow.com/questions/4631565/java-how-to-restart-a-static-class) –