web-dev-qa-db-ja.com

JUnit 5では、すべてのテストの前にコードを実行する方法

@BeforeAll注釈は、classのすべてのテストの前に実行するメソッドをマークします。

http://junit.org/junit5/docs/current/user-guide/#writing-tests-annotations

しかし、すべてのクラスで、allテストの前にいくつかのコードを実行する方法はありますか?

テストでデータベース接続の特定のセットを使用し、これらの接続のグローバルワンタイムセットアップを実行する必要があることを確認したいbeforerunninganyテスト。

21
Rob N

現在、これはサポートされていませんが、このトピックに関するJUnit 5のプルリクエストがあります: テストの実行ごとに1回の前/後コールバックのサポートを導入します

5
Stefan Birkner

これは、カスタムの拡張機能を作成することにより、JUnit5で可能になりました。この拡張機能から、ルートテストコンテキストにシャットダウンフックを登録できます。

拡張機能は次のようになります。

import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import static org.junit.jupiter.api.extension.ExtensionContext.Namespace.GLOBAL;

public class YourExtension implements BeforeAllCallback, ExtensionContext.Store.CloseableResource {

    private static boolean started = false;

    @Override
    public void beforeAll(ExtensionContext context) {
        if (!started) {
            started = true;
            // Your "before all tests" startup logic goes here
            // The following line registers a callback hook when the root test context is shut down
            context.getRoot().getStore(GLOBAL).put("any unique name", this);
        }
    }

    @Override
    public void close() {
        // Your "after all tests" logic goes here
    }
}

次に、これを少なくとも1回実行する必要があるテストクラスには、次の注釈を付けることができます。

@ExtendWith({YourExtension.class})

この拡張機能を複数のクラスで使用すると、起動とシャットダウンのロジックは1回だけ呼び出されます。

24
Philipp Gayret

データベースを使用する各テストクラスを、staticBeforeAllを定義するインターフェイスでマークできます(オーバーライドできないようにするため)。例えば。:

interface UsesDatabase {
    @BeforeAll
    static void initializeDatabaseConnections() {
        // initialize database connections
    }
}

このメソッドは実装するクラスごとに1回呼び出されるため、接続を1回だけ初期化し、他の呼び出しには何もしない方法を定義する必要があります。

3
mfulton26

私はそれをする意味を知りません。

@BeforeAllのすべてのコードが特定のシングルトンを呼び出して、そのinitが機能するようにします(おそらく、繰り返しを避けるために怠zyな方法で)。

おそらく便利ではない...私が見る他の唯一のオプション:テストは特定のJVMジョブ内で実行されると思います。あなたはcouldをフックagentそのJVMの実行にフックします。

それを超えて:両方の提案は、どういうわけか私にハックのように聞こえます。私の目にはreal答え:戻って、依存関係について環境を注意深く調べてください。そして、テストが起動し、「正しいこと」が自動的に行われるように、環境をprepareする方法を見つけます。言い換えれば、この問題を買ったアーキテクチャを調べることを検討してください。

1
GhostCat

上記のアドバイスはnot私のために働くので、この問題を次のように解決しました:

Base抽象クラスに追加します(setUpDriver()メソッドでドライバーを初期化する抽象クラスを意味します):

private static boolean started = false;
static{
    if (!started) {
        started = true;
        try {
            setUpDriver();  //method where you initialize your driver
        } catch (MalformedURLException e) {
        }
    }
}

そして今、テストクラスがextends Base抽象クラスから->setUpDriver()メソッドが最初の@の前に実行される場合テストのみ[〜#〜] one [〜#〜]プロジェクト実行ごとの時間。

1
Sergii