static イニシャライザを握りつぶす
はじめに
JUnitでテストコードを書くにあたって、JMockitを使用して適宜モック化してテストを実施していました。 staticイニシャライザにテストとは関係ないコードがあったので実行しないようにモック化したかったのですが、JMockitによるモック化はできなそうだったのでJavassistを使用して解決することにしました。
解決方法
CtClassからstaticイニシャライザオブジェクトを取得できるので、setBodyメソッドを実行してメソッドの中身を書き換えればOK
※Javassistそのものの説明は省きます
package cpp0302.test; /** モック化対象のクラス */ public class Hoge { private static int count; static { // 検証用に無理やり例外を発生させる count = 1 / 0; } public static void printCount() { System.out.println("count: " + count); } }
CrushStaticInitializer.java
package cpp0302.test; import javassist.ClassPool; import javassist.CtClass; import javassist.CtConstructor; public class CrushStaticInitializer { public static void main(String[] args) throws Exception { ClassPool cp = ClassPool.getDefault(); cp.appendSystemPath(); CtClass hogeClass = cp.get("cpp0302.test.crush.Hoge"); CtConstructor classInitializer = hogeClass.getClassInitializer(); // staticイニシャライザの内容を変更 classInitializer.setBody("{ count = 78; System.out.println(\"staticイニシャライザを握りつぶした\"); }"); hogeClass.toClass(); // クラスメソッド実行前にstaticイニシャライザが実行される Hoge.printCount(); } }
実行結果
staticイニシャライザを握りつぶした count: 78
これでテストコード実行に関係ない処理を握りつぶすことができました