ここでは、静的初期化子を使用するユーティリティークラスを再ロードして、そのユーティリティーの初期化をテストする小さな例を示します。 ユーティリティは、システムプロパティを使用して静的最終値を初期化します。通常、この値は実行時には変更できません。 だから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を変更することはできますが、あなたはそれを禁止されているようです。唯一の他の選択肢は、クラスを再ロードするためにプライベートクラスローダーとリフレクションを使用することです。しかし、 'Foo.getBar()'呼び出しを再作成する必要があります。 –
[Java:静的クラスを "再起動する"方法](http://stackoverflow.com/questions/4631565/java-how-to-restart-a-static-class) –