開発環境でいくつかのサービスをモックしようとしています。serviceFactory コードは次のようなものです。
public class ApiFacadeImpl implements ApiFacade {
private OneService oneService = null;
public OneService getOneService(){
if(oneService==null) {//some initialization steps }
return oneService;
}
}
私は、この工場が適切にコーディングおよび設計されていないことを知っています。ただし、そのコードを変更することはできません。私の考えは、バイトコードを変更することなので、次のように再定義できます。
public class ApiFacadeImpl implements ApiFacade {
private OneService oneService = new MyMockOneService();
....
}
私の1番目は、これはjavassistを使用して可能ですか? そしてどうやって?
Googleを使用してjavassistを使用してフィールドを再初期化するようなものが見つからないので、それを削除して再作成してみました:
CtField oneServiceField = cc.getDeclaredField("oneService");
cc.removeField(oneServiceField);
CtField f = CtField.make(String.format("private %s %s=new %s();",
oneServiceField.getType().getName(), "oneService",
mockClass.getCanonicalName()), cc);
cc.addField(f);
cc.toClass();
それから私は例外を得ました:
javassist.CannotCompileException: by java.lang.ClassFormatError: Invalid length 99 in LocalVariableTable in class file com/Test
at javassist.ClassPool.toClass(ClassPool.java:1051)
at javassist.ClassPool.toClass(ClassPool.java:994)
at javassist.ClassPool.toClass(ClassPool.java:952)
at javassist.CtClass.toClass(CtClass.java:1079)
私の2番目の質問は、なぜこの例外なのですか? Javaクラスの定義に従わないステップはどれですか? そして、フィールドを削除すると、javassistは次のフィールド参照を削除するのに役立ちます:
public OneService getOneService(){
if(oneService==null) {//some initialization steps }
return oneService;
}
どうもありがとう。