JUnit 5中的ExternalResource和TemporaryFolder的等价物是什么?

时间:2017-05-18 23:38:35

标签: java junit temporary-files junit5

根据JUnit 5 User Guide,JUnit Jupiter为某些JUnit 4规则提供了向后兼容性,以便协助迁移。

  

如上所述,JUnit Jupiter本身不支持也不支持JUnit 4规则。然而,JUnit团队意识到许多组织,特别是大型组织,可能拥有大型JUnit 4代码库,包括自定义规则。为了服务这些组织并实现渐进式迁移路径,JUnit团队决定在JUnit Jupiter中逐字支持一系列JUnit 4规则。

该指南接着说其中一条规则是ExternalResource,它是TemporaryFolder的父级。

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

5 个答案:

答案 0 :(得分:5)

Interesting article by author of TemporaryFolderExtension for JUnit5

his code repo on github

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>

答案 1 :(得分:4)

该文档仍在制作中 - 请参阅pull request #660

答案 2 :(得分:4)

JUnit 5.4带有一个内置扩展,可以处理测试中的临时目录。

可以使用

@org.junit.jupiter.api.io.TempDir注释来注释类字段或生命周期中的参数(例如@BeforeEach)或类型为FilePath的测试方法。

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

答案 3 :(得分:3)

据我所知,从ExternalResource到JUnit5中的等价物没有一对一的映射。这些概念不合适。在JUnit4中,ExternalResource基本上会为您提供beforeafter回调,但在规则范围内,您无法控制实际beforeafter手段。您可以将其与@Rule@ClassRule一起使用。

在JUnit5中,扩展名被定义为挂钩特定的extension points,因此'when'被很好地定义。

概念的另一个不同之处在于,您可以在JUnit4规则中拥有状态,但您的JUnit5扩展不应具有任何状态。相反,所有州都应该转到execution context

尽管如此,这是我提供的一个选项,其中beforeafter与每种测试方法相关:

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

答案 4 :(得分:0)

临时文件夹现在具有@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();
    }

}

您当然可以将所有内容包装成一个抽象类,并且MyResourceExtension仅实现protected void before()protected void after()或类似的东西,如果那是您的事,但是我省略了为简洁起见。