JUnit 5ユーザーガイド によると、JUnit Jupiterは、移行を支援するために、一部のJUnit4ルールに下位互換性を提供します。
上記のように、JUnitJupiterはJUnit4ルールをネイティブにサポートしていません。ただし、JUnitチームは、多くの組織、特に大規模な組織では、カスタムルールを含む大規模なJUnit4コードベースを使用する可能性が高いことを認識しています。これらの組織にサービスを提供し、段階的な移行パスを有効にするために、JUnitチームは、JUnitJupiter内で逐語的にJUnit4ルールの選択をサポートすることを決定しました。
ガイドはさらに、ルールの1つは ExternalResource であり、これは TemporaryFolder の親であると述べています。
ただし、残念ながら、このガイドでは、移行パスとは何か、または新しいJUnit5テストを作成する場合の同等のパスについては説明していません。では、何を使うべきでしょうか?
JUnit 5.4には、テストで一時ディレクトリを処理するための拡張機能が組み込まれています。
@org.junit.jupiter.api.io.TempDir
アノテーションは、ライフサイクル内のクラスフィールドまたはパラメータにアノテーションを付けるために使用できます(例:@BeforeEach
)またはタイプFile
またはPath
のテストメソッド。
import org.junit.jupiter.api.io.TempDir;
@Test
void writesContentToFile(@TempDir Path tempDir) throws IOException {
// arrange
Path output = tempDir
.resolve("output.txt");
// act
fileWriter.writeTo(output.toString(), "test");
// assert
assertAll(
() -> assertTrue(Files.exists(output)),
() -> assertLinesMatch(List.of("test"), Files.readAllLines(output))
);
}
これについての詳細は、私のブログ投稿で読むことができます。ここでは、この組み込み拡張機能の利用に関するいくつかの例を見つけることができます。 https://blog.codeleak.pl/2019/03/temporary-directories-in- junit-5-tests.html 。
JUnit5のTemporaryFolderExtensionの作者による興味深い記事
そして
JUnit5.0.0は現在一般リリースされているので、実験的なものを本番環境に対応させることに注意を向けることを期待しましょう。
一方、TemporaryFolderルールは引き続きJUnit5で機能するようです docs
これを使って:
@EnableRuleMigrationSupport
public class MyJUnit5Test {
この:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-migrationsupport</artifactId>
<version>5.0.0</version>
</dependency>
そのためのドキュメントはまだ作成中です プルリクエスト#66 を参照してください。
私が理解している限り、ExternalResource
からJUnit5の同等のものへの1対1のマッピングはあり得ません。概念はちょうど適合しません。 JUnit4では、ExternalResource
は基本的にbefore
とafter
コールバックを提供しますが、ルール内では、before
とafter
が実際に何を意味するかを制御することはできません。 @Rule
または@ClassRule
と一緒に使用できます。
JUnit5では、拡張機能は特定の 拡張ポイント にフックするように定義されているため、「when」は適切に定義されています。
概念のもう1つの違いは、JUnit4ルールに状態を含めることはできますが、JUnit5拡張機能に状態を含めることはできないということです。代わりに、すべての状態は 実行コンテキスト に移動する必要があります。
それにもかかわらず、ここに私が持ってきたオプションがあります。ここで、before
とafter
は各テストメソッドに関連しています。
public abstract class ExternalResourceExtension
implements BeforeTestExecutionCallback, AfterTestExecutionCallback {
@Override
public void beforeTestExecution(ExtensionContext context) throws Exception {
before(context);
}
@Override
public void afterTestExecution(ExtensionContext context) throws Exception {
after(context);
}
protected abstract void before(ExtensionContext context);
protected abstract void after(ExtensionContext context);
}
一時フォルダには、 _@TempDir
_ という方法で解決策があります。しかし、一般的にExternalResource
sの背後にある考え方はどうですか?おそらく、モックデータベース、モックHTTP接続、またはサポートを追加したいその他のカスタムリソース用ですか?
答えは、 _@RegisterExtension
_ アノテーションを使用して、非常によく似たものを実現できることがわかりました。
使用例:
_/**
* This is my resource shared across all tests
*/
@RegisterExtension
static final MyResourceExtension MY_RESOURCE = new MyResourceExtension();
/**
* This is my per test resource
*/
@RegisterExtension
final MyResourceExtension myResource = new MyResourceExtension();
@Test
void test() {
MY_RESOURCE.doStuff();
myResource.doStuff();
}
_
そして、これがMyResourceExtension
の基本的な足場です。
_public class MyResourceExtension implements BeforeAllCallback, AfterAllCallback,
BeforeEachCallback, AfterEachCallback {
private SomeResource someResource;
private int referenceCount;
@Override
public void beforeAll(ExtensionContext context) throws Exception {
beforeEach(context);
}
@Override
public void afterAll(ExtensionContext context) throws Exception {
afterEach(context);
}
@Override
public void beforeEach(ExtensionContext context) throws Exception {
if (++referenceCount == 1) {
// Do stuff in preparation
this.someResource = ...;
}
}
@Override
public void afterEach(ExtensionContext context) throws Exception {
if (--referenceCount == 0) {
// Do stuff to clean up
this.someResource.close();
this.someResource = null;
}
}
public void doStuff() {
return this.someResource.fooBar();
}
}
_
もちろん、これをすべて抽象クラスとしてまとめて、MyResourceExtension
にprotected void before()
やprotected void after()
などを実装させることもできますが、それは私です。簡潔にするためにそれを省略します。