一、概述

在本教程中,咱们将学习如何从 JUnit 4 迁徙到最新的 JUnit 5 版本,并介绍两个版本的库之间的差别。

无关应用 JUnit 5 的个别指南,请参阅咱们的文章 此处。

二、JUnit 5 的劣势

让咱们从以前的版本 JUnit 4 开始,它有一些显著的限度:

  • 单个 jar 库蕴含整个框架。咱们须要导入整个库,即便咱们只须要一个特定的性能。 在 JUnit 5 中,咱们取得了更多的粒度,并且能够只导入必要的内容。
  • 在 JUnit 4 中一次只有一个测试运行器能够执行测试(例如 SpringJUnit4ClassRunnerParameterized )。 JUnit 5 容许多个跑步者同时工作。
  • JUnit 4 从未超过 Java 7,错过了 Java 8 的许多个性。JUnit 5 充分利用了 Java 8 个性。

JUnit 5 背地的想法是齐全重写 JUnit 4 以打消这些毛病中的大部分。

三、差别

JUnit 4 被划分为组成 JUnit 5 的模块:

  • JUnit Platform -- 此模块涵盖了咱们可能感兴趣的所有扩大框架:测试执行、发现和报告。
  • JUnit Vintage -- 此模块容许向后兼容 JUnit 4 甚至 JUnit 3。

3.1。正文

JUnit 5 对其正文进行了重要更改。 最重要的一点是咱们不能再应用 @Test 正文来指定冀望。

JUnit 4 中的 expected 参数:

@Test(expected = Exception.class)public void shouldRaiseAnException() throws Exception {    // ...}

当初咱们能够应用办法assertThrows

public void shouldRaiseAnException() throws Exception {    Assertions.assertThrows(Exception.class, () -> {        //...    });}

JUnit 4 中的 timeout 属性:

@Test(timeout = 1)public void shouldFailBecauseTimeout() throws InterruptedException {    Thread.sleep(10);}

当初 JUnit 5 中的 assertTimeout 办法:

@Testpublic void shouldFailBecauseTimeout() throws InterruptedException {    Assertions.assertTimeout(Duration.ofMillis(1), () -> Thread.sleep(10));}

以下是在 JUnit 5 中的一些更新:

  • @Before annotation is now @BeforeEach
  • @After annotation is now @AfterEach
  • @BeforeClass annotation is now @BeforeAll
  • @AfterClass annotation is now @AfterAll
  • @Ignore annotation is now @Disabled

3.2。断言

咱们还能够在 JUnit 5 的 lambda 中编写断言音讯,以便跳过简单的音讯结构:

@Testpublic void shouldFailBecauseTheNumbersAreNotEqual_lazyEvaluation() {    Assertions.assertTrue(      2 == 3,       () -> "Numbers " + 2 + " and " + 3 + " are not equal!");}

此外,咱们能够在 JUnit 5 中对断言进行分组:

@Testpublic void shouldAssertAllTheGroup() {    List<Integer> list = Arrays.asList(1, 2, 4);    Assertions.assertAll("List is not incremental",        () -> Assertions.assertEquals(list.get(0).intValue(), 1),        () -> Assertions.assertEquals(list.get(1).intValue(), 2),        () -> Assertions.assertEquals(list.get(2).intValue(), 3));}

3.3。假如

新的 Assumptions 类当初位于 org.junit.jupiter.api.Assumptions 中。 JUnit 5 齐全反对 JUnit 4 中现有的假如办法,并且还增加了一组新办法,容许咱们仅在特定场景下运行一些断言:

@Testpublic void whenEnvironmentIsWeb_thenUrlsShouldStartWithHttp() {    assumingThat("WEB".equals(System.getenv("ENV")),      () -> {          assertTrue("http".startsWith(address));      });}

3.4。标记和过滤

在 JUnit 4 中,咱们能够应用 @Category 正文对测试进行分组。在 JUnit 5 中,@Category 正文被 @Tag 正文替换:

@Tag("annotations")@Tag("junit5")public class AnnotationTestExampleTest {    /*...*/}

咱们能够应用 maven-surefire-plugin 蕴含/排除特定标签:

<build>    <plugins>        <plugin>            <artifactId>maven-surefire-plugin</artifactId>            <configuration>                <properties>                    <includeTags>junit5</includeTags>                </properties>            </configuration>        </plugin>    </plugins></build>

3.5。运行测试的新正文

在 JUnit 4 中,咱们应用 @RunWithannotation 将测试上下文与其余框架集成,或者更改测试用例中的整体执行流程。

在 JUnit 5 中,咱们当初能够应用 @ExtendWith 正文来提供相似的性能。

例如,要应用 JUnit 4 中的 Spring 性能:

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(  {"/app-config.xml", "/test-data-access-config.xml"})public class SpringExtensionTest {    /*...*/}

在 JUnit 5 中,这是一个简略的扩大:

@ExtendWith(SpringExtension.class)@ContextConfiguration(  { "/app-config.xml", "/test-data-access-config.xml" })public class SpringExtensionTest {    /*...*/}

3.6。新的测试规定正文

在 JUnit 4 中,咱们应用 @Rule 和 @ClassRule 正文向测试增加非凡性能。

在 JUnit 5 中,咱们能够应用 @ExtendWith 正文重现雷同的逻辑。

例如,假如咱们在 JUnit 4 中有一个自定义规定,用于在测试之前和之后编写日志跟踪:

public class TraceUnitTestRule implements TestRule {     @Override    public Statement apply(Statement base, Description description) {        return new Statement() {            @Override            public void evaluate() throws Throwable {                // Before and after an evaluation tracing here                 ...            }        };    }}

咱们在一个测试套件中实现它:

@Rulepublic TraceUnitTestRule traceRuleTests = new TraceUnitTestRule();

在 JUnit 5 中,咱们能够用更直观的形式编写雷同的代码:

public class TraceUnitExtension implements AfterEachCallback, BeforeEachCallback {    @Override    public void beforeEach(TestExtensionContext context) throws Exception {        // ...    }    @Override    public void afterEach(TestExtensionContext context) throws Exception {        // ...    }}

应用 org.junit.jupiter.api.extension 包中提供的 JUnit 5 的 AfterEachCallbackBeforeEachCallback 接口,咱们能够在测试套件中轻松实现此规定:

@ExtendWith(TraceUnitExtension.class)public class RuleExampleTest {     @Test    public void whenTracingTests() {        /*...*/    }}

3.7。 JUnit 5 Vintage

JUnit Vintage 通过在 JUnit 5 上下文中运行 JUnit 3 或 JUnit 4 测试来帮忙迁徙 JUnit 测试。

咱们能够通过导入 JUnit Vintage Engine 来应用它:

<dependency>    <groupId>org.junit.vintage</groupId>    <artifactId>junit-vintage-engine</artifactId>    <version>${junit5.vintage.version}</version>    <scope>test</scope></dependency>

四、论断

JUnit 5 是对 JUnit 4 框架的模块化和现代版。在本文中,咱们介绍了这两个版本之间的次要区别,并展现了如何从一个版本迁徙到另一个版本。

本文的残缺实现能够在 GitHub 中找到。