0

jUnit テスト内のアプリケーション コンテキストに内部 Bean をプログラムで追加しようとしています。@Component同じコンテキスト内で実行される他のすべてのテストに影響を与えるため、Bean にアノテーションを付けてコンテキストを汚染したくありません。

public class PatchBaseImplTest extends TestBase{

    /**
     * Sample test patch to modify the schema
     */
    public class SchemaUpdatePatch extends PatchBaseImpl {
        public SchemaUpdatePatch(){
            super();
        }

        @Override
        public void applyPatch() throws Exception {
        }
    };

    @Before
    public void setUp(){
        // add patch to context
        beanRegistry.registerBeanDefinition("SchemaUpdatePatch",  SchemaUpdatePatch.class,  BeanDefinition.SCOPE_PROTOTYPE);
        schemaPatch = (Patch)applicationContext.getBean("SchemaUpdatePatch", SchemaUpdatePatch.class);

    }
}

registerBeanDefinition は次のように定義されます。

    public void registerBeanDefinition( String name, Class clazz, String scope){
        GenericBeanDefinition definition = new GenericBeanDefinition();
        definition.setBeanClass(clazz);
        definition.setScope(scope);
        definition.setAutowireCandidate(true);
        definition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_BY_TYPE);

        registry.registerBeanDefinition(name,  definition);
    }

Bean 定義がアプリケーション コンテキストに追加されていることがわかりますが、appContext.getBean() を使用して Bean を取得しようとすると、クラスにコンストラクターがないというエラーが Spring によってスローされます。

Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.ia.system.patch.PatchBaseImplTest$SchemaUpdatePatch]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.ia.system.patch.PatchBaseImplTest$SchemaUpdatePatch.<init>()
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:83)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1000)
    ... 35 more
Caused by: java.lang.NoSuchMethodException: com.ia.system.patch.PatchBaseImplTest$SchemaUpdatePatch.<init>()
    at java.lang.Class.getConstructor0(Class.java:2800)
    at java.lang.Class.getDeclaredConstructor(Class.java:2043)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:78)
    ... 36 more

デフォルトのコンストラクターを SchemaUpdatePatch クラスに追加しようとしましたが、問題ではないようです。

ただし、プログラムでコンテキストに追加する代わりに @Component で注釈を付け、applicationContext.getBean() を介してアクセスしようとすると、正常に動作します。

この Bean をプログラムで applicationContext に追加する正しい方法は何ですか? 私の GenericBeanDefinition は間違っていますか? コンストラクターが何であるかを指定するために何か不足していますか?

4

1 に答える 1

1

この投稿を書くことは、実際にはカタルシスでした。バグ/エラーを見つけるのに役立ちました。内部クラスを Static にする必要があるか、Spring がインスタンス化できません。うまくいけば、これは将来誰かを助けるかもしれません。

すなわち:

/**
 * Sample test patch to modify the schema
 */
static public class SchemaUpdatePatch extends PatchBaseImpl {
    public SchemaUpdatePatch(){
        super();
    }

    @Override
    public void applyPatch() throws Exception {
    }
};
于 2013-10-18T18:55:31.780 に答える