3

抽象テスト クラスの次のコードがあります ( XmlBeanFactorywithClassPathResourceが推奨されていないことはわかっていますが、問題が発生する可能性は低いです)。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public abstract class AbstractIntegrationTest {

    /** Spring context. */
    protected static final BeanFactory context = new XmlBeanFactory(new ClassPathResource(
            "com/.../AbstractIntegrationTest-context.xml"));

    ...

}

デフォルトのテスト構成 XML ファイルをロードしますAbstractIntegrationTest-context.xml(そして、オートワイヤーを使用します)。@BeforeClassまた、 andで注釈が付けられた静的メソッドで Spring を使用する必要が@AfterClassあるため、同じ場所を指す別のコンテキスト変数があります。しかし問題は、これは別のコンテキストであり、Bean の異なるインスタンスを持つことです。@ContextConfigurationでは、これらのコンテキストをマージするにはどうすればよいか、または静的コンテキストからによって定義された Spring の Bean 初期化を呼び出すにはどうすればよいでしょうか?

これらの静的メンバーを取り除くことで可能な解決策を念頭に置いていますが、コードに比較的小さな変更を加えて解決できるかどうか、興味があります。

4

2 に答える 2

8

おっしゃるとおり、コードは 2 つのアプリケーション コンテキストを生成します。1 つは、@ContextConfiguration注釈によって開始され、キャッシュされ、維持されます。自分で作成する 2 番目のコンテキスト。両方持っていてもあまり意味がありません。

残念ながら、JUnit は統合テストにはあまり適していません。主な理由は、before クラスafter クラスの非静的メソッドを使用できないためです。2 つの選択肢があります。

  • に切り替える- これは大きな一歩だと思います

  • テスト中にのみコンテキストに含まれるSpring Beanにセットアップ/破棄ロジックをエンコードしますが、すべてのテストの前に一度だけ実行されます。

エレガントではないアプローチもあります。変数を使用staticして、それにコンテキストを注入できます。

private static ApplicationContext context;

@AfterClass
public static afterClass() {
    //here context is accessible
}

@Autowired
public void setApplicationContext(ApplicationContext applicationContext) {
    context = applicationContext;
}

または、テストクラスに注釈を付けて@DirtiesContext、いくつかのテスト Bean でクリーンアップを行うことができます。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@DirtiesContext(classMode = AFTER_CLASS)
public abstract class AbstractIntegrationTest {

    //...

}

public class OnlyForTestsBean {

    @PreDestroy
    public void willBeCalledAfterEachTestClassDuringShutdown() {
        //..
    }

}
于 2012-08-29T16:38:57.063 に答える
6

ここでアプローチを選択したかどうかはわかりませんが、同じ問題に遭遇し、Spring テスト フレームワークの を使用して別の方法で解決しましたTestExecutionListener

beforeTestClassとがあるので、どちらもJUnit のとにafterTestClass相当します。@BeforeClass@AfterClass

私のやり方:

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners(Cleanup.class)
@ContextConfiguration(locations = { "/integrationtest/rest_test_app_ctx.xml" })
public abstract class AbstractIntegrationTest {
    // Start server for integration test.
}

AbstractTestExecutionListener を拡張するクラスを作成する必要があります。

public class Cleanup extends AbstractTestExecutionListener
{

   @Override
   public void afterTestClass(TestContext testContext) throws Exception
   {
      System.out.println("cleaning up now");
      DomainService domainService=(DomainService)testContext.getApplicationContext().getBean("domainService");
      domainService.delete();

   }
}

これにより、アプリケーション コンテキストにアクセスし、ここで Spring Bean を使用してセットアップ/破棄を行うことができます。

これが、私のように JUnit + Spring を使用して統合テストを行おうとしている人に役立つことを願っています。

于 2013-11-06T07:20:55.040 に答える