web-dev-qa-db-ja.com

静的@BeforeClassでフィールドを自動配線する方法は?

@RunWith(SpringJUnit4ClassRunner.class)
public void ITest {
    @Autowired
    private EntityRepository dao;

    @BeforeClass
    public static void init() {
        dao.save(initialEntity); //not possible as field is not static
    }
}

静的initクラスにサービスを既に挿入するにはどうすればよいですか?

31
membersound

あなたはテストの前にDBを投入しようとしているように見えます。

私は2つのオプションを試してみます:

  • 初期スクリプトをsqlファイルに抽出できる場合(リポジトリBeanを使用しないオプションの場合) このアプローチ を使用し、@Sqlでテストに注釈を付けることができます
  • DbUnit を調べることができます。ここに spring dbunitコネクタへのリンク があります。これは、スプリングテストフレームワークとdbunitを統合するための github link です。これを実行すると、@DatabaseSetup@DatabaseTearDownが得られ、DBで必要なことを実行できます

これは、Beanを静的@BeforeClassに注入する方法には答えませんが、コードを作成することで問題を解決できることがわかります。

更新:最近プロジェクトで同じ問題にぶつかり、掘り出しました この記事 助けてくれて、エレガントだと思いますこのタイプの問題に対処する方法。 SpringJUnit4ClassRunnerをリスナーで拡張すると、定義済みのすべてのBeanでインスタンスレベルのセットアップを実行できます。

8
Nenad Bozic

これを機能させるために使用してきた回避策の1つは、@Before各テストケースで実行されることをスキップするフラグ付き

@RunWith(SpringJUnit4ClassRunner.class)
public class BaseTest {

@Autowired
private Service1 service1;

@Autowired
private Service2 service2;

private static boolean dataLoaded = false;

@Before
public void setUp() throws Exception {

    if (!dataLoaded) {
        service1.something();
        service2.somethingElse();
        dataLoaded = true;
    }
  }
}
16
Narain Mittal

この質問に答えるには、Spring 2.xバージョンを要約する必要があります。

_@BeforeTest_クラスでBeanを「自動配線」する場合は、ApplicationContextインターフェイスを使用できます。例を見てみましょう:

_@BeforeClass
    public static void init() {
        ApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
        EntityRepository dao2 = (EntityRepository) context.getBean("dao");
        List<EntityRepository> all = dao2.getAll();
        Assert.assertNotNull(all);
    }
_

何が起こっているのか:ClassPathXmlApplicationContextを使用して、_application-context.xml_ファイルに含まれるすべてのBeanをインスタンス化しています。

context.getBean()を使用して、指定されたBeanを読み取ります(Beanの名前と一致する必要があります!);その後、初期化に使用できます。

Beanに別の名前(_dao2_!)を付ける必要があります。そうしないと、Springの通常の「自動接続」は事前定義されたBeanで機能しません。

サイドノートとして、テストが_AbstractTransactionalJUnit4SpringContextTests_を拡張する場合、executeSqlScript(sqlResourcePath, continueOnError);を使用して初期化を行うことができます。メソッドなので、クラス/メソッドに依存せずに、個別にテストする必要もあります。

3
musikele

Spring 2.xバージョンのUPD。

Spring 2.xは、Junit 5 Jupiterの新機能a SpringExtensionをサポートしています。

  1. @ExtendWith(SpringExtension.class)を使用してテストクラスを宣言します

  2. @BeforeAll(JUnit 5の@BeforeClassの置き換え)にBeanを挿入します

例えば:

@ExtendWith(SpringExtension.class)
...
public void ITest {

    @BeforeAll
    public static void init(@Autowired EntityRepository dao) {
        dao.save(initialEntity);
    }

}

Spring 2.xでJUnit 5 Jupiterを正しく構成したと仮定します

詳細はこちら: https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#testcontext-junit-jupiter-extension

0
yeralin