JUnit 5 中的 ExternalResource 和 TemporaryFolder 等价物是什么?
What is the equivalent of ExternalResource and TemporaryFolder in JUnit 5?
根据 JUnit 5 User Guide,JUnit Jupiter 为某些 JUnit 4 规则提供向后兼容性以协助迁移。
As stated above, JUnit Jupiter does not and will not support JUnit 4 rules natively. The JUnit team realizes, however, that many organizations, especially large ones, are likely to have large JUnit 4 codebases including custom rules. To serve these organizations and enable a gradual migration path the JUnit team has decided to support a selection of JUnit 4 rules verbatim within JUnit Jupiter.
指南继续说其中一条规则是 ExternalResource, which is a parent for TemporaryFolder。
但是,不幸的是,该指南没有继续说明迁移路径是什么,或者对于那些编写新的 JUnit 5 测试的等效路径是什么。那我们应该怎么用呢?
相关文档仍在制作中 - 请参阅 pull request #660。
Interesting article by author of TemporaryFolderExtension for JUnit5
和
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>
据我所知,从 ExternalResource
到 JUnit5 中的等价物没有一对一的映射。这些概念只是不适合。在 JUnit4 中,ExternalResource
基本上给你一个 before
和一个 after
回调,但在规则内,你无法控制 before
和 after
实际上是什么方法。您可以将它与 @Rule
或 @ClassRule
.
一起使用
在 JUnit5 中,扩展定义为挂钩特定 extension points,因此 'when' 定义明确。
概念上的另一个区别是,您可以在 JUnit4 规则中有一个状态,但您的 JUnit5 扩展不应该有任何状态。相反,所有状态都应该转到 execution context.
然而,这是我提出的一个选项,其中 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);
}
JUnit 5.4 带有一个内置扩展来处理测试中的临时目录。
@org.junit.jupiter.api.io.TempDir
注释可用于注释 class 字段或生命周期中的参数(例如 @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))
);
}
您可以在我的博客 post 中阅读更多相关信息,您可以在其中找到更多关于使用此内置扩展的示例:https://blog.codeleak.pl/2019/03/temporary-directories-in-junit-5-tests.html。
临时文件夹现在有@TempDir
的解决方法。但是,一般来说 ExternalResource
背后的想法是什么?可能是针对模拟数据库、模拟 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();
}
}
你当然可以把这一切都包装成一个抽象的 class 并让 MyResourceExtension
只实现 protected void before()
和 protected void after()
或类似的东西,如果那是你的事,但为简洁起见,我将其省略。
根据 JUnit 5 User Guide,JUnit Jupiter 为某些 JUnit 4 规则提供向后兼容性以协助迁移。
As stated above, JUnit Jupiter does not and will not support JUnit 4 rules natively. The JUnit team realizes, however, that many organizations, especially large ones, are likely to have large JUnit 4 codebases including custom rules. To serve these organizations and enable a gradual migration path the JUnit team has decided to support a selection of JUnit 4 rules verbatim within JUnit Jupiter.
指南继续说其中一条规则是 ExternalResource, which is a parent for TemporaryFolder。
但是,不幸的是,该指南没有继续说明迁移路径是什么,或者对于那些编写新的 JUnit 5 测试的等效路径是什么。那我们应该怎么用呢?
相关文档仍在制作中 - 请参阅 pull request #660。
Interesting article by author of TemporaryFolderExtension for JUnit5
和
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>
据我所知,从 ExternalResource
到 JUnit5 中的等价物没有一对一的映射。这些概念只是不适合。在 JUnit4 中,ExternalResource
基本上给你一个 before
和一个 after
回调,但在规则内,你无法控制 before
和 after
实际上是什么方法。您可以将它与 @Rule
或 @ClassRule
.
在 JUnit5 中,扩展定义为挂钩特定 extension points,因此 'when' 定义明确。
概念上的另一个区别是,您可以在 JUnit4 规则中有一个状态,但您的 JUnit5 扩展不应该有任何状态。相反,所有状态都应该转到 execution context.
然而,这是我提出的一个选项,其中 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);
}
JUnit 5.4 带有一个内置扩展来处理测试中的临时目录。
@org.junit.jupiter.api.io.TempDir
注释可用于注释 class 字段或生命周期中的参数(例如 @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))
);
}
您可以在我的博客 post 中阅读更多相关信息,您可以在其中找到更多关于使用此内置扩展的示例:https://blog.codeleak.pl/2019/03/temporary-directories-in-junit-5-tests.html。
临时文件夹现在有@TempDir
的解决方法。但是,一般来说 ExternalResource
背后的想法是什么?可能是针对模拟数据库、模拟 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();
}
}
你当然可以把这一切都包装成一个抽象的 class 并让 MyResourceExtension
只实现 protected void before()
和 protected void after()
或类似的东西,如果那是你的事,但为简洁起见,我将其省略。