75、单元测试-嵌套测试

75、单元测试-嵌套测试

**嵌套测试**是JUnit 5提供的一种功能,允许将测试类组织成层次结构,提升测试代码的可读性和可维护性。

什么是嵌套测试?

嵌套测试通过`@Nested`注解,将测试类定义为外部类的**内部类**,形成嵌套结构。每个嵌套类可以包含自己的测试方法,以及`@BeforeEach`、`@AfterEach`等生命周期方法。

优点

  1. **逻辑分组**:将相关的测试用例按功能或状态分组,使代码结构更清晰。

  2. **共享上下文**:内部类可以访问外部类的成员变量和方法,方便共享测试数据和设置。

  3. **独立生命周期**:每个嵌套类可以有独立的初始化和清理方法,减少重复代码。

使用示例

```java

import org.junit.jupiter.api.*;

public class ShoppingCartTest {

private ShoppingCart cart;

@BeforeEach

void init() {

cart = new ShoppingCart();

}

@Nested

@DisplayName("空购物车")

class EmptyCart {

@Test

@DisplayName("总金额应为0")

void totalPriceShouldBeZero() {

assertEquals(0, cart.getTotalPrice());

}

@Test

@DisplayName("移除商品应抛出异常")

void removeItemShouldThrowException() {

assertThrows(IllegalStateException.class, () -> cart.removeItem("apple"));

}

}

@Nested

@DisplayName("添加商品后")

class WithItems {

@BeforeEach

void addItem() {

cart.addItem("apple", 2);

cart.addItem("banana", 3);

}

@Test

@DisplayName("总金额应正确")

void totalPriceShouldBeCorrect() {

assertEquals(2 * 5 + 3 * 3, cart.getTotalPrice());

}

@Nested

@DisplayName("移除商品")

class AfterRemovingItem {

@Test

@DisplayName("移除存在的商品")

void removeExistingItem() {

cart.removeItem("apple");

assertEquals(3, cart.getItemCount());

}

@Test

@DisplayName("移除不存在的商品应抛出异常")

void removeNonExistingItem() {

assertThrows(IllegalArgumentException.class, () -> cart.removeItem("orange"));

}

}

}

}

```

注意事项

  • **非静态内部类**:`@Nested`类必须是非静态的,以便访问外部类的成员。

  • **执行顺序**:嵌套测试的执行顺序是从外到内,但同层级的嵌套类之间顺序不确定。

  • **嵌套层级**:建议嵌套层级不超过3层,过深的嵌套会降低代码可读性。

  • **生命周期方法**:嵌套类可以有自己的`@BeforeEach`和`@AfterEach`方法,但不会继承外部类的这些方法。

适用场景

  • **复杂对象的状态测试**:例如,购物车的空状态、添加商品状态、结算状态等。

  • **分层测试逻辑**:将初始化、操作、验证等步骤分到不同的嵌套类中。

  • **多配置组合测试**:测试不同配置下的对象行为。

通过合理使用嵌套测试,可以有效地组织和管理测试代码,提高单元测试的可读性和维护性。

相关推荐
M--Y1 分钟前
LangChain 提示工程:少样本提示与输出解析器
python·langchain·大模型·llm·输出解析器·少样本提示
朱包林1 分钟前
iTerm2终端配置指南
linux·javascript·python·云原生·容器·kubernetes·云计算
棉猴3 分钟前
玩游戏学Python5-函数
开发语言·python·函数·玩游戏·游戏编程
Rain的Java大神之路4 分钟前
[特殊字符]8年Java老兵转型AI Agent:90%的人挂在同一个坑,根本不用学Python!(万字实战复盘,建议收藏)
java·数据库·人工智能·后端·python·spring·ai编程
高级程序源18 分钟前
springboot本地生活服务平台33399-计算机课程设计、毕业设计
vue.js·spring boot·python·mysql·小程序·flask·课程设计
高级程序源23 分钟前
springboot社区旧物回收管理系统25381-计算机课程设计、毕业设计
vue.js·spring boot·python·django·课程设计
高级程序源25 分钟前
springboot大学生体测系统72170-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·python·django·课程设计
谢亮_vipxieliang30 分钟前
JavaScript this 指向完全指南:调用位置决定一切
开发语言·javascript·ecmascript
码途行者34 分钟前
缓存一致性难题:Redis 和数据库如何做到数据一致?
数据库·redis
打工仔折腾 AI38 分钟前
极空间用 Docker 部署 Photopea:网页版 PS 的私有化实践
运维·后端·python·docker·容器·langchain·ai agent 实战