Java JUnit5中的ExternalResource和TemporaryFolder的等价物是什么?

Java JUnit5中的ExternalResource和TemporaryFolder的等价物是什么?,java,junit,temporary-files,junit5,Java,Junit,Temporary Files,Junit5,根据,JUnitJupiter为一些JUnit4规则提供向后兼容性,以帮助迁移 如上所述,JUnit Jupiter在本机上不支持也不会支持JUnit4规则。然而,JUnit团队意识到,许多组织,尤其是大型组织,可能有大型JUnit4代码库,包括自定义规则。为了服务于这些组织并实现渐进的迁移路径,JUnit团队决定在JUnit Jupiter中支持选择JUnit4规则 该指南接着说,其中一条规则是,这是孩子的父母 然而,不幸的是,指南没有继续说明迁移路径是什么,或者对于编写新JUnit5测试的人

根据,JUnitJupiter为一些JUnit4规则提供向后兼容性,以帮助迁移

如上所述,JUnit Jupiter在本机上不支持也不会支持JUnit4规则。然而,JUnit团队意识到,许多组织,尤其是大型组织,可能有大型JUnit4代码库,包括自定义规则。为了服务于这些组织并实现渐进的迁移路径,JUnit团队决定在JUnit Jupiter中支持选择JUnit4规则

该指南接着说,其中一条规则是,这是孩子的父母


然而,不幸的是,指南没有继续说明迁移路径是什么,或者对于编写新JUnit5测试的人来说,等效的迁移路径是什么。那么我们应该使用什么呢?

这方面的文档仍在制作中-请参阅。

JUnit5.0.0现在已经正式发布,所以我们希望他们将注意力转移到准备好实验材料的生产上

同时,临时文件夹规则似乎仍然适用于JUnit5

使用以下命令:

@EnableRuleMigrationSupport
public class MyJUnit5Test {
这是:

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-migrationsupport</artifactId>
    <version>5.0.0</version>
</dependency>

org.junit.jupiter
junit jupiter迁移支持
5.0.0

据我所知,在JUnit5中不可能有从
ExternalResource
到等效资源的一对一映射。这些概念根本不合适。在JUnit4中,
ExternalResource
基本上为您提供了一个
before
before
回调,但在规则中,您无法控制
before
after
的实际含义。您可以将其与
@Rule
@ClassRule
一起使用

在JUnit5中,扩展被定义为特定的钩子,因此“when”定义得很好

概念上的另一个区别是,在JUnit4规则中可以有一个状态,但JUnit5扩展不应该有任何状态。相反,所有的州都应该去美国

尽管如此,我还是提供了一个选项,其中
之前
之后
与每个测试方法相关:

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);
}

JUnit5.4附带了一个内置扩展来处理测试中的临时目录

@org.junit.jupiter.api.io.TempDir
注释可用于注释生命周期中的类字段或参数(例如,
@beforeach
)或类型为
文件
路径
的测试方法

import org.junit.jupiter.api.io.TempDir;
@试验
void writeContentToFile(@TempDir Path TempDir)引发IOException{
//安排
路径输出=tempDir
.resolve(“output.txt”);
//表演
writeTo(output.toString(),“test”);
//断言
资产(
()->assertTrue(Files.exists(output)),
()->assertLinesMatch(List.of(“test”)、Files.readAllLines(输出))
);
}

您可以在我的博客文章中阅读更多关于这方面的内容,在这里您可以找到更多关于使用此内置扩展的示例:。

临时文件夹现在有了一个解决方案。然而,一般来说,
ExternalResource
s背后的想法是什么?可能是针对模拟数据库、模拟HTTP连接或其他您想要添加支持的自定义资源

答案是,您可以使用注释来实现类似的功能

使用示例:

/**
 * 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
实现
protectedvoid before()
protectedvoid before()
或诸如此类,如果这是您的事情,但为了简洁起见,我省略了它。

此功能是实验性的,所以我不想使用它。ExternalResource在设置所有测试使用的或有对象之前是可用的,如果扩展不能有任何实例成员,如何替换这个功能?知道扩展之外的代码应该如何获取扩展准备的任何东西(比如EJB容器)吗?