1. 概要

通常、 @ BeforeEach、@ AfterEach、@ BeforeAll、 @ AfterAll、などのJUnitアノテーションを使用して、テストのライフサイクルを調整しますが、それだけでは不十分な場合もあります。 Springフレームワークでの作業。

ここで、Spring TestExecutionListenerが役に立ちます。

このチュートリアルでは、 TestExecutionListenerが提供するもの、Springが提供するデフォルトのリスナー、およびカスタムTestExecutionListenerを実装する方法を確認します。

2. TestExecutionListenerインターフェイス

まず、TestExecutionListenerインターフェイスにアクセスしてみましょう。

public interface TestExecutionListener {
    default void beforeTestClass(TestContext testContext) throws Exception {};
    default void prepareTestInstance(TestContext testContext) throws Exception {};
    default void beforeTestMethod(TestContext testContext) throws Exception {};
    default void afterTestMethod(TestContext testContext) throws Exception {};
    default void afterTestClass(TestContext testContext) throws Exception {};
}

このインターフェースの実装は、さまざまなテスト実行段階でイベントを受け取ることができます。 その結果、インターフェイスの各メソッドにはTestContextオブジェクトが渡されます。

このTestContextオブジェクトには、Springコンテキスト、およびターゲットのテストクラスとメソッドの情報が含まれています。 この情報を使用して、テストの動作を変更したり、テストの機能を拡張したりできます。

それでは、これらの各メソッドを簡単に見てみましょう。

  • afterTestClass –クラス内のすべてのテストの実行後にテストクラスを後処理します
  • afterTestExecution –提供されたテストコンテキストでテストメソッドを実行した直後にテストを後処理します
  • afterTestMethod –基盤となるテストフレームワークのライフサイクル後のコールバックの実行後にテストを後処理します
  • beforeTestClass –クラス内のすべてのテストを実行する前にテストクラスを前処理します
  • beforeTestExecution –提供されたテストコンテキストでテストメソッドを実行する直前にテストを前処理します
  • beforeTestMethod –基盤となるテストフレームワークのbefore-lifecycleコールバックの実行前にテストを前処理します
  • prepareTestInstance –提供されたテストコンテキストのテストインスタンスを準備します

このインターフェースは、すべてのメソッドに空のデフォルト実装を提供することに注意してください。 したがって、具体的な実装では、目前のタスクに適したメソッドのみをオーバーライドすることを選択できます。

3. SpringのデフォルトTestExecutionListeners

デフォルトでは、SpringはいくつかのTestExecutionListener実装をすぐに提供します。

これらのそれぞれを簡単に見てみましょう。

  • ServletTestExecutionListener WebApplicationContextのサーブレットAPIモックを構成します
  • DirtiesContextBeforeModesTestExecutionListener –「前」モードの@DirtiesContextアノテーションを処理します
  • DependencyInjectionTestExecutionListener –テストインスタンスに依存性注入を提供します
  • DirtiesContextTestExecutionListener –「後」モードの@DirtiesContextアノテーションを処理します
  • TransactionalTestExecutionListener –デフォルトのロールバックセマンティクスでトランザクションテストの実行を提供します
  • SqlScriptsTestExecutionListener @Sqlアノテーションを使用して構成されたSQLスクリプトを実行します

これらのリスナーは、リストされている順序で正確に事前登録されています。 カスタムTestExecutionListenerを作成すると、注文の詳細がわかります。

4. カスタムTestExecutionListenerの使用

次に、カスタムTestExecutionListenerを定義しましょう。

public class CustomTestExecutionListener implements TestExecutionListener, Ordered {
    private static final Logger logger = LoggerFactory.getLogger(CustomTestExecutionListener.class);
    
    public void beforeTestClass(TestContext testContext) throws Exception {
        logger.info("beforeTestClass : {}", testContext.getTestClass());
    }; 
    
    public void prepareTestInstance(TestContext testContext) throws Exception {
        logger.info("prepareTestInstance : {}", testContext.getTestClass());
    }; 
    
    public void beforeTestMethod(TestContext testContext) throws Exception {
        logger.info("beforeTestMethod : {}", testContext.getTestMethod());
    }; 
    
    public void afterTestMethod(TestContext testContext) throws Exception {
        logger.info("afterTestMethod : {}", testContext.getTestMethod());
    }; 
    
    public void afterTestClass(TestContext testContext) throws Exception {
        logger.info("afterTestClass : {}", testContext.getTestClass());
    }

    @Override
    public int getOrder() {
        return Integer.MAX_VALUE;
    };
}

簡単にするために、このクラスが行うのは、TestContext情報の一部をログに記録することだけです。

4.1. @TestExecutionListenersを使用したカスタムリスナーの登録

それでは、このリスナーをテストクラスで使用してみましょう。 これを行うには、@TestExecutionListenersアノテーションを使用して登録します。

@RunWith(SpringRunner.class)
@TestExecutionListeners(value = {
  CustomTestExecutionListener.class,
  DependencyInjectionTestExecutionListener.class
})
@ContextConfiguration(classes = AdditionService.class)
public class AdditionServiceUnitTest {
    // ...
}

アノテーションを使用すると、すべてのデフォルトリスナーの登録が解除されることに注意してください。 したがって、 DependencyInjectionTestExecutionListener を明示的に追加して、テストクラスで自動配線を使用できるようにしました。

他のデフォルトリスナーのいずれかが必要な場合は、それぞれを指定する必要があります。 ただし、アノテーションのmergeModeプロパティを使用することもできます。

@TestExecutionListeners(
  value = { CustomTestExecutionListener.class }, 
  mergeMode = MergeMode.MERGE_WITH_DEFAULTS)

ここで、 MERGE_WITH_DEFAULTS は、ローカルで宣言されたリスナーをデフォルトのリスナーとマージする必要があることを示しています。

上記のテストを実行すると、リスナーは受信した各イベントをログに記録します。

[main] INFO  o.s.t.c.s.DefaultTestContextBootstrapper - Using TestExecutionListeners: 
[com.baeldung.testexecutionlisteners.CustomTestExecutionListener@38364841, 
org.springframework.test.context.support.DependencyInjectionTestExecutionListener@28c4711c]
[main] INFO  c.b.t.CustomTestExecutionListener - beforeTestClass : 
class com.baeldung.testexecutionlisteners.TestExecutionListenersWithoutMergeModeUnitTest
[main] INFO  c.b.t.CustomTestExecutionListener - prepareTestInstance : 
class com.baeldung.testexecutionlisteners.TestExecutionListenersWithoutMergeModeUnitTest
[main] INFO  o.s.c.s.GenericApplicationContext - 
Refreshing org.springframework.context.support.GenericApplicationContext@7d68ef40: startup date [XXX]; 
root of context hierarchy
[main] INFO  c.b.t.CustomTestExecutionListener - beforeTestMethod : 
public void com.baeldung.testexecutionlisteners.TestExecutionListenersWithoutMergeModeUnitTest
.whenValidNumbersPassed_thenReturnSum()
[main] INFO  c.b.t.CustomTestExecutionListener - afterTestMethod : 
public void com.baeldung.testexecutionlisteners.TestExecutionListenersWithoutMergeModeUnitTest
.whenValidNumbersPassed_thenReturnSum()
[main] INFO  c.b.t.CustomTestExecutionListener - afterTestClass : 
class com.baeldung.testexecutionlisteners.TestExecutionListenersWithoutMergeModeUnitTest

4.2. デフォルトのTestExecutionListener実装の自動検出

@TestExecutionListener を使用してリスナーを登録することは、限られた数のテストクラスで使用される場合に適しています。 ただし、テストスイート全体に追加するのは面倒になる可能性があります。

SpringFactoriesLoader メカニズムによって提供されるサポートを利用して、 TestExecutionListener 実装の自動検出を行うことで、この問題に対処できます。

spring-test モジュールは、 META-INF /spring.factoriesプロパティのorg.springframework.test.context.TestExecutionListenerキーの下ですべてのコアデフォルトリスナーを宣言しますファイル。 同様に、独自のMETA-INF / spring.factoriesプロパティファイルで上記のキーを使用して、カスタムリスナーを登録できます。

org.springframework.test.context.TestExecutionListener=\
com.baeldung.testexecutionlisteners.CustomTestExecutionListener

4.3. デフォルトのTestExecutionListener実装の注文

SpringがSpringFactoriesLoaderメカニズムを介してデフォルトのTestExecutionListener 実装を検出すると、SpringのAnnotationAwareOrderComparatorを使用してそれらを並べ替えます。これは尊重されます。 SpringのOrderedインターフェースと注文用の@Orderアノテーション。

Springによって提供されるすべてのデフォルトのTestExecutionListener実装は、適切な値でOrderedを実装することに注意してください。 したがって、カスタムTestExecutionListener実装が正しい順序で登録されていることを確認する必要があります。 その結果、カスタムリスナーにOrderedを実装しました。

public class CustomTestExecutionListener implements TestExecutionListener, Ordered {
    // ...
    @Override
    public int getOrder() {
        return Integer.MAX_VALUE;
    };
}

ただし、代わりに@Orderアノテーションを使用できます

5. 結論

この記事では、カスタムTestExecutionListenerを実装する方法を説明しました。 また、Springフレームワークによって提供されるデフォルトのリスナーについても調べました。

そしてもちろん、この記事に付随するコードはGitHubで入手できます。