行业资讯 2025年08月6日
0 收藏 0 点赞 931 浏览 3475 个字
摘要 :

文章目录 1.默认情况下,@BeforeAll和@AfterAll方法是“静态的” 2. 将@BeforeAll和@AfterAll方法作为非静态方法 3. 示例 4.结论 自JUnit 4以来,用于设置和拆卸操作的@B……




  • 1.默认情况下,@BeforeAll和@AfterAll方法是“静态的”
  • 2. 将@BeforeAll和@AfterAll方法作为非静态方法
  • 3. 示例
  • 4.结论

自JUnit 4以来,用于设置和拆卸操作的@BeforeClass和@AfterClass方法必须声明为静态方法。在JUnit 5中,此限制已经解除,我们也可以在非静态方法上使用等效的@BeforeAll和@AfterAll注解,从而提供更多的灵活性和使用实例特定的设置和清理逻辑的能力。

在本JUnit 5教程中,我们将学习编写非静态@BeforeAll和@AfterAll方法,通过使用@TestInstance(TestInstance.Lifecycle.PER_CLASS)注解我们的测试,从而在它们中访问测试实例特定的变量。

1.默认情况下,@BeforeAll和@AfterAll方法是“静态的”

在JUnit 5中,@BeforeAll和@AfterAll方法必须声明为静态方法,这意味着它们与测试类本身相关联,而不是与类的实例相关联。

有时,这可能会成为一种限制,例如,当并行运行测试时。在并行执行环境中,静态方法可能会引入并发问题,但非静态方法确保每个测试实例是隔离的。

public class TestClass {
  @BeforeAll
  static void setupBeforeAll() {
    //所有测试之前的类特定设置逻辑
  }
  @AfterAll
  static void cleanupAfterAll() {
    // 所有测试后的类特定清理逻辑
  }
  @Test
  void test1() {
    // 测试1逻辑
  }
  @Test
  void test2() {
    // 测试2逻辑
  }
}

2. 将@BeforeAll和@AfterAll方法作为非静态方法

要在JUnit 5中编写和使用非静态@BeforeAll和@AfterAll方法,我们必须使用@TestInstance(TestInstance.Lifecycle.PER_CLASS)注解测试类。这表明我们希望使用非静态测试实例生命周期。这确保JUnit为每个测试类创建一个新的测试实例。

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class TestClass {
  //...
}

在上面的示例中,@BeforeAll和@AfterAll方法是非静态的。这使它们能够访问实例特定的数据或执行实例特定的设置和清理操作。

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class TestClass {
  @BeforeAll
  void setupBeforeAll() {
    // 所有测试之前,特定实例的设置逻辑。
  }
  @AfterAll
  void cleanupAfterAll() {
    // 所有测试之后,特定实例的清理逻辑。
  }
  @Test
  void test1() {
    // Test 1 logic.
  }
  @Test
  void test2() {
    // Test 2 logic.
  }
}

3. 示例

假设我们有一个购物车模块,我们想在并发环境中测试其功能。我们编写了以下测试类,该类利用购物车作为列表,并测试添加/删除操作。

我们多次并发地运行测试10次。

public class TestNonStaticBeforeAllAndAfterAll {
  private static List<String> cart = new ArrayList<>();
  @BeforeAll
  static void setupBeforeAll() {
    System.out.println(\"Setting up the shopping cart for all tests\");
    cart.add(\"Item 1\");
    cart.add(\"Item 2\");
  }
  @AfterAll
  static void cleanupAfterAll() {
    System.out.println(\"Cleaning up the shopping cart after all tests\");
    cart.clear();
  }
  @RepeatedTest(10)
  @Execution(ExecutionMode.CONCURRENT)
  void testAddItemToCart() {
    cart.add(\"Item 3\");
    // 添加商品并断言其存在于购物车的测试逻辑。
  }
  @RepeatedTest(10)
  @Execution(ExecutionMode.CONCURRENT)
  void testRemoveItemFromCart() {
    cart.remove(\"Item 1\");
    cart.remove(\"Item 2\");
    cart.remove(\"Item 3\");
    // 删除商品并断言其不存在于购物车的测试逻辑。
  }
}

此外,我们通过设置以下属性文件/src/test/resources/junit-platform.properties将顶级类的默认执行模式配置为并行。

junit.jupiter.execution.parallel.enabled = true
junit.jupiter.execution.parallel.mode.default = concurrent
junit.jupiter.execution.parallel.mode.classes.default = concurrent

现在,当我们多次运行测试类时,由于在不同的测试类实例中并发地访问购物车,几次测试将会失败。

java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 10
    at java.base/java.util.ArrayList.fastRemove(ArrayList.java:724)
    at java.base/java.util.ArrayList.remove(ArrayList.java:711)
    at com.howtodoinjava.junit5.examples.TestNonStaticBeforeAllAndAfterAll
            .testRemoveItemFromCart(TestNonStaticBeforeAllAndAfterAll.java:39)

JUnit 5 非静态@BeforeAll和@AfterAll方法为了解决这个问题,我们将在本文的第一部分进行推荐更改,即测试生命周期为PER_CLASS。这是更新的测试类。

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class TestNonStaticBeforeAllAndAfterAll {
  private List<String> cart = new ArrayList<>();
  @BeforeAll
  void setupBeforeAll() {
    System.out.println(\"Setting up the shopping cart for all tests\");
    cart.add(\"Item 1\");
    cart.add(\"Item 2\");
  }
  @AfterAll
  void cleanupAfterAll() {
    System.out.println(\"Cleaning up the shopping cart after all tests\");
    cart.clear();
  }
  @RepeatedTest(10)
  @Execution(ExecutionMode.CONCURRENT)
  void testAddItemToCart() {
    cart.add(\"Item 3\");
    // 添加商品并断言其存在于购物车的测试逻辑。
  }
  @RepeatedTest(10)
  @Execution(ExecutionMode.CONCURRENT)
  void testRemoveItemFromCart() {
    cart.remove(\"Item 1\");
    cart.remove(\"Item 2\");
    cart.remove(\"Item 3\");
    //删除商品并断言其不存在于购物车的测试逻辑。
  }
}

现在,当在并发环境中再次运行测试类时,所有的测试都会通过。JUnit 5 非静态@BeforeAll和@AfterAll方法

4.结论

在这篇JUnit 5教程中,我们学会了使用非静态的@BeforeAll和@AfterAll方法来帮助在这些设置和收尾方法中访问测试实例特定的变量。为了快速参考,我们需要用@TestInstance(TestInstance.Lifecycle.PER_CLASS)注解我们的测试。

微信扫一扫

支付宝扫一扫

版权: 转载请注明出处:https://www.zuozi.net/9566.html

管理员

相关推荐
2025-08-06

文章目录 一、Reader 接口概述 1.1 什么是 Reader 接口? 1.2 Reader 与 InputStream 的区别 1.3 …

988
2025-08-06

文章目录 一、事件溯源 (一)核心概念 (二)Kafka与Golang的优势 (三)完整代码实现 二、命令…

465
2025-08-06

文章目录 一、证明GC期间执行native函数的线程仍在运行 二、native线程操作Java对象的影响及处理方…

348
2025-08-06

文章目录 一、事务基础概念 二、MyBatis事务管理机制 (一)JDBC原生事务管理(JdbcTransaction)…

456
2025-08-06

文章目录 一、SnowFlake算法核心原理 二、SnowFlake算法工作流程详解 三、SnowFlake算法的Java代码…

517
2025-08-06

文章目录 一、本地Jar包的加载操作 二、本地Class的加载方法 三、远程Jar包的加载方式 你知道Groo…

832
发表评论
暂无评论

还没有评论呢,快来抢沙发~

助力内容变现

将您的收入提升到一个新的水平

点击联系客服

在线时间:08:00-23:00

客服QQ

122325244

客服电话

400-888-8888

客服邮箱

122325244@qq.com

扫描二维码

关注微信客服号