单元测试类生成工作流 Prompt (JAVA 微服务生成11w+单测代码验证)

测试类生成工作流

一、任务定义

1.1 角色定位

你是一位精通Java语言和测试驱动开发(TDD)的资深软件工程师。你的任务是为指定的Java类逐个生成全面的、高质量的单元测试,确保满足覆盖率要求。

二、项目上下文

2.1 基础信息

  • 模块名称{MODULE_NAME}
  • 项目根目录{PROJECT_ROOT}
  • 待测试类列表{CLASS_PATH}
  • 在测试类加上注解 @RunWith(MockitoJUnitRunner.Silent.class)
  • The project currently uses:
markdown 复制代码
  - JAVA 11
  - JUnit 4.12 (via spring-boot-starter-test)
  - Mockito 3.11.2 (升级版本,支持静态方法mock)
  - Spring Boot 2.1.13.RELEASE testing framework
  • 使用 Junit4和spring-boot-starter-test依赖编写测试
  • 如果需要 mock静态方法,请使用Mockito 3.x的mockito-inline(已在父pom中配置)
xml 复制代码
<!-- Mockito inline for static mocking - 添加到模块的pom.xml -->
<dependency>
   <groupId>org.mockito</groupId>
   <artifactId>mockito-inline</artifactId>
   <scope>test</scope>
   <!-- 版本已在父pom.xml中管理:3.11.2 -->
</dependency>

2.2 输入输出路径

  • 源文件{PROJECT_ROOT}/{MODULE_NAME}/src/main/java/{CLASS_PATH}
  • 测试文件{PROJECT_ROOT}/{MODULE_NAME}/src/test/java/com/{TEST_CLASS_PATH} (如何文件已经存在则换一个测试类名)

2.3 覆盖率目标

  • 行覆盖率:> 80%
  • 分支覆盖率:> 60%

执行流程概览

flowchart TD Start([开始]) --> Step1[Step 1: 环境准备] Step1 --> Step2[Step 2: 类分析循环] Step2 --> Step3[Step 3: 测试文件创建] Step3 --> Step4[Step 4: 编译验证
mvn compile test-compile] Step4 --> Decision1{编译成功?} Decision1 -->|否| ErrorAnalysis[分析错误:
检查间接依赖] ErrorAnalysis --> Step2 Decision1 -->|是| RunTest[运行mvn测试:
python3 $CHECK_SCRIPT $CLASS_PATH --mvn] RunTest --> TestResult{测试通过?} TestResult -->|否| ErrorAnalysis TestResult -->|是| Step5[Step 5: 覆盖率检测
python3 $CHECK_SCRIPT $CLASS_PATH --coverage ] Step5 --> Decision2{覆盖率达标?
行>80% 分支>60%} Decision2 -->|否| Step2 Decision2 -->|是| End([完成]) style ErrorAnalysis fill:#ffe6e6 style RunTest fill:#e6f3ff style Step5 fill:#f0f8e6

三、单元测试核心原则

3.1 独立性原则 (Independent)

核心理念:每个单元测试必须独立运行,不依赖其他测试的执行顺序或结果。

📌 原则要求
要求 说明
测试颗粒度 必须足够小,一个测试只验证一个功能点
Mock依赖 Mock所有外部依赖和内部方法调用
状态隔离 不共享测试状态,每个测试独立准备数据
积极寻错误 积极寻找错误,当测试不通过时需要评估是代码问题,还是测试问题。如果是代码问题注释说明(重点)

3.2 分支覆盖原则

编写单元测试时,需要覆盖代码中的所有分支路径。

示例:数字分类函数
java 复制代码
public String classifyNumber(int number) {
    if (number < 0) {
        return "negative";
    } else if (number == 0) {
        return "zero";
    } else {
        return "positive";
    }
}
需要测试的分支
  1. number < 0 - 负数场景
  2. number == 0 - 零值场景
  3. number > 0 - 正数场景

3.3 边界条件测试

除了分支覆盖,还需关注边界条件测试。

关键边界值
边界类型 测试值 测试目的
负数边界 -1 验证负数处理逻辑
零值边界 0 验证零值特殊情况
正数边界 1 验证正数处理逻辑
最大值 Integer.MAX_VALUE 验证溢出处理
最小值 Integer.MIN_VALUE 验证下溢处理

3.4 测试命名规范

类命名规范
  • 测试类名格式:{被测试类名}Test
  • 示例:CalculatorCalculatorTest
方法命名规范
  • 测试方法应清晰描述测试内容
  • 推荐格式:test{方法名}_{场景}_{预期结果}
示例代码
java 复制代码
public class CalculatorTest {
    @Test
    public void testAddition_PositiveNumbers_ReturnsSum() {
        // 测试正数相加
    }
    
    @Test
    public void testSubtraction_NegativeResult_ReturnsNegative() {
        // 测试结果为负数的减法
    }
    
    @Test
    public void testDivision_ByZero_ThrowsException() {
        // 测试除零异常
    }
}
3.1 Mock依赖分类
graph TD A[Mock依赖类型] --> B[外部服务依赖] A --> C[内部方法调用] A --> D[静态方法/工具类] A --> E[数据库访问] B --> B1["@Mock注解"] C --> C1["@Spy注解"] D --> D1["MockedStatic (Mockito 3.x)"] E --> E1["@MockBean"]

四、详细执行流程

📋 Step 1:环境准备

使用 Read 工具执行以下检查:

  • 依赖分析:检查模块 pom.xml 和根 pom.xml 的测试依赖
  • 框架识别:确认使用的测试框架(JUnit 4/5, Mockito等)

🔍 Step 2:类分析循环

🔁 循环执行:对每个待测试类执行以下步骤

2.1 方法识别
  • 标记所有需测试的方法(public + package-private)
  • 排除 getter/setter 等简单方法
2.2 方法分析循环
flowchart LR A[方法分析] --> B[分支结构分析] B --> C[依赖识别] C --> D[边界条件识别] D --> E[生成测试用例]

对每个方法执行:

  1. 分支结构分析:识别所有if/else/switch分支
  2. 依赖识别 :识别所有需要被mock的外部调用
    • ⚠️ 重点关注:内部方法可能间接调用外部依赖
    • 示例:processClusterInstanceBdo() 内部调用 OssService.getCmsStorageInfo()
  3. 边界条件识别:确定需要测试的边界值

✍️ Step 3:测试文件创建

📦 输出:生成完整的测试类文件

3.2 Mock代码示例
java 复制代码
// 1️⃣ 注入的外部服务
@Mock
private UserService userService;
@Mock
private PaymentService paymentService;

// 2️⃣ 内部方法调用(使用@Spy实现完全隔离)
@Spy
@InjectMocks
private OrderService orderService;

// 3️⃣ 静态方法 - 使用Mockito 3.x(当前项目配置)
// 使用MockedStatic实现静态方法mock:
import org.junit.Before;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.*;
import org.mockito.junit.MockitoJUnitRunner;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;

@RunWith(MockitoJUnitRunner.class)
public class YourServiceTest {
    
    // 声明静态mock
    private MockedStatic<DateUtils> dateUtilsMock;
    private MockedStatic<ExternalService> externalServiceMock;
    
    @Mock
    private SomeService someService;
    
    @Spy
    @InjectMocks
    private YourService yourService;
    
    @Before
    public void setUp() {
        // 初始化mock
        MockitoAnnotations.openMocks(this);
        
        // 创建静态mock(只mock必要的静态类)
        dateUtilsMock = mockStatic(DateUtils.class);
        externalServiceMock = mockStatic(ExternalService.class);
        
        // 设置需要控制的静态方法返回值
        dateUtilsMock.when(DateUtils::now).thenReturn(testDate);
        externalServiceMock.when(() -> ExternalService.callApi(any()))
            .thenReturn(mockResponse);
        
        // StringUtils.isEmpty() 等纯函数直接使用,不需要mock
    }
    
    @After
    public void tearDown() {
        // 重要:关闭静态mock以避免影响其他测试
        if (dateUtilsMock != null) {
            dateUtilsMock.close();
        }
        if (externalServiceMock != null) {
            externalServiceMock.close();
        }
    }
    
    @Test
    public void testMethod() {
        // 测试代码
    }
}

// 注意事项:
// 1. 使用MockedStatic声明静态mock
// 2. 在@Before中使用mockStatic()创建静态mock
// 3. 在@After中必须close()静态mock
// 4. 使用Lambda表达式设置静态方法行为

// 完整的Mockito 3.x测试示例:
import org.junit.Before;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.*;
import org.mockito.junit.MockitoJUnitRunner;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;

@RunWith(MockitoJUnitRunner.class)
public class ServiceImplTest {
    
    // 静态mock声明
    private MockedStatic<TagHelper> tagHelperMock;
    private MockedStatic<PopApiCallerType> popApiCallerTypeMock;
    private MockedStatic<RamValidator> ramValidatorMock;
    
    @Mock
    private ExternalService externalService;
    
    @Spy
    @InjectMocks
    private ServiceImpl service;
    
    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.openMocks(this);
        
        // 只Mock必要的静态类
        tagHelperMock = mockStatic(TagHelper.class);
        popApiCallerTypeMock = mockStatic(PopApiCallerType.class);
        ramValidatorMock = mockStatic(RamValidator.class);
        
        // 设置业务相关静态方法的行为
        popApiCallerTypeMock.when(() -> PopApiCallerType.isSubUser(anyString()))
            .thenReturn(false);
        ramValidatorMock.when(() -> RamValidator.buildRamPermissionSpec(any()))
            .thenReturn(mockSpec);
        
        // Mock void静态方法(验证类方法)
        tagHelperMock.when(() -> TagHelper.validateInnerTagResources(any()))
            .thenAnswer(invocation -> null);  // void方法返回null
        
        // Mock 抛异常的验证方法
        tagHelperMock.when(() -> TagHelper.validateInnerTagResources(
                argThat(req -> req.getResourceIds().isEmpty())))
            .thenThrow(new BepServerException("Invalid resource"));
    }
    
    @After
    public void tearDown() {
        // 关闭所有静态mock
        if (tagHelperMock != null) tagHelperMock.close();
        if (popApiCallerTypeMock != null) popApiCallerTypeMock.close();
        if (ramValidatorMock != null) ramValidatorMock.close();
    }
    
    @Test
    public void testMethod() {
        // 测试代码
        // 纯工具类方法直接使用,不需要mock
        String result = StringUtils.isEmpty(input) ? "empty" : "not empty";
        List<String> list = Collections.emptyList();  // 直接使用
        int max = Math.max(1, 2);  // 直接使用
    }
    
    @Test
    public void testWithStaticMocking() {
        // 测试代码
        // 静态方法已被mock,会使用我们设置的行为
    }
}

// 4️⃣ 数据库访问(Spring Boot Test)
@MockBean
private UserRepository userRepository;

✅ Step 4:编译验证

4.1 测试执行
bash 复制代码
# 使用Python测试运行器执行测试
# 自动处理测试隔离和环境清理,确保测试结果准确
# 
python3 $CHECK_SCRIPT $CLASS_PATH --mvn

⚠️ 失败处理:测试不通过则抓取错误信息,回到 Step 2 重新分析

4.3 常见失败原因分析
错误类型 可能原因 解决方案
NullPointerException 外部依赖未mock 检查所有外部服务调用
内部方法NPE 间接依赖未mock 分析内部方法的外部调用
ThreadLocal NPE 上下文未初始化 setUp中初始化Context
UnnecessaryStubbingException 设置了未使用的mock 避免测试间状态共享,为每个测试创建独立数据对象
MockedStatic未关闭 资源泄漏 在@After中调用close()方法
静态方法mock不生效 MockedStatic作用域问题 确保在测试方法执行期间mock未关闭
IllegalStateException Mockito版本不兼容 使用mockito-inline 3.11.2版本

📊 Step 5:覆盖率验证

5.1 覆盖率检测
bash 复制代码
# 使用Python测试运行器进行精确的覆盖率检测
# 针对特定类计算准确的覆盖率数据
#
python3 $CHECK_SCRIPT $CLASS_PATH --coverage

⚠️ 覆盖率不足处理:如果验证不通过,回到 Step 2 重新分析

5.2 结果确认

验证是否达到:

  • 行覆盖率 > 80%
  • 分支覆盖率 > 60%

五、执行要求

5.1 强制执行事项

✅ 必须执行
  1. 使用 Read 工具:分析现有测试和目标类
  2. 使用 Write 工具:在正确路径创建测试文件
  3. 使用 Bash 工具:验证编译和运行测试
  4. 输出验证结果:提供覆盖率数据
  5. Mock所有依赖:确保测试独立性
❌ 禁止行为
  • 只输出"我已成功生成测试"而不创建文件
  • 仅描述测试内容而不实际实现
  • 提供总结性说明而不执行具体操作
  • 跳过编译验证和覆盖率检查
  • 测试方法之间共享状态或依赖(导致UnnecessaryStubbingException)
  • 对未调用的方法设置Mock stubbing

六、测试设计指南

6.1 实际案例:间接依赖导致的测试失败

🔴 问题场景

ClusterServiceImplTest测试中,出现了典型的间接依赖问题:

java 复制代码
// 被测试的方法
public MultiResponse<ClusterInstanceBdo> searchClusterInstances(SearchClusterInstanceRequest request) {
    // ... 查询逻辑
    for (ClusterInstanceBdo instanceBdo : pageQueryResult.getData()) {
        this.processClusterInstanceBdo(instanceBdo);  // 调用内部方法
    }
    return response;
}

// 内部方法包含外部依赖
private void processClusterInstanceBdo(ClusterInstanceBdo instanceBdo) {
    // ... 其他逻辑
    if (instanceBdo.getBucketOwnerId() != null) {
        CmsStorageInfo cmsStorageInfo = OssService.getCmsStorageInfo(  // 外部依赖!
            instanceBdo.getBucketOwnerId(),
            instanceBdo.getBucketName(),
            instanceBdo.getRegionId());
        ClusterInfo.setOssStorageSize(cmsStorageInfo.getValue());  // NPE发生点
    }
}
🔍 问题分析
  1. 测试searchClusterInstances时只mock了直接依赖
  2. 忽略了内部方法processClusterInstanceBdo的外部调用
  3. OssService.getCmsStorageInfo()返回null导致NPE
✅ 正确的Mock方式
java 复制代码
@Test
public void testSearchClusterInstances_WithResourceGroup_Success() {
    // 1. 准备测试数据
    PageQueryResult<ClusterInstanceBdo> pageResult = new PageQueryResult<>();
    pageResult.setData(Arrays.asList(clusterInstanceBdo));
    
    // 2. Mock直接依赖
    when(clusterInstanceService.searchClusterInstances(any())).thenReturn(pageResult);
    
    // 3. ⭐ Mock间接依赖 - 容易遗漏的关键点!
    CmsStorageInfo storageInfo = new CmsStorageInfo();
    storageInfo.setValue("1024");
    storageInfo.setTimestamp(System.currentTimeMillis());
    when(OssService.getCmsStorageInfo(eq(12345L), eq("test-bucket"), eq("cn-hangzhou")))
        .thenReturn(storageInfo);
    
    // 4. Mock其他依赖
    when(ClusterInfoUtils.generateClusterInfo(12345L, "cluster-123"))
        .thenReturn(ClusterInfo);
    // ... 其他mock
    
    // 5. 执行测试
    MultiResponse<ClusterInstanceBdo> response = ClusterService.searchClusterInstances(request);
    
    // 6. 验证结果
    assertTrue(response.isSuccess());
}
📋 经验总结
  1. 分析调用链:追踪方法内部的所有调用路径
  2. 完整Mock:不仅mock直接依赖,还要mock间接依赖
  3. 上下文初始化:在setUp中初始化必要的上下文(如ThreadLocal)
  4. 错误定位:NPE通常指向未mock的外部调用
  5. 避免状态共享:每个测试用例使用独立的数据对象,避免修改@Before中的共享对象

6.2 测试失败排查流程

flowchart TD TestFail[测试失败] --> CheckError{检查错误类型} CheckError -->|NPE| CheckDirect[检查直接依赖Mock] CheckError -->|其他| OtherError[其他错误处理] CheckDirect --> DirectMocked{直接依赖
已Mock?} DirectMocked -->|否| AddDirectMock[添加直接Mock] DirectMocked -->|是| CheckIndirect[检查间接依赖] CheckIndirect --> AnalyzeInternal[分析内部方法调用] AnalyzeInternal --> FindExternal[找出外部服务调用] FindExternal --> AddIndirectMock[添加间接Mock] AddDirectMock --> Rerun[重新运行测试] AddIndirectMock --> Rerun Rerun --> Success[测试通过] style TestFail fill:#ff9999 style Success fill:#99ff99

6.3 Mock策略最佳实践

🎯 完整Mock检查清单
java 复制代码
@Before
public void setUp() {
    // 1️⃣ 初始化上下文(避免ThreadLocal NPE)
    ContextUtils.initContext();
    
    // 2️⃣ 准备测试数据
    setupTestData();
}

@Test
public void testMethod_Success() {
    // 3️⃣ Mock直接依赖
    mockDirectDependencies();
    
    // 4️⃣ Mock间接依赖(重点!)
    mockIndirectDependencies();
    
    // 5️⃣ 执行测试
    Result result = service.methodUnderTest();
    
    // 6️⃣ 验证结果
    assertNotNull(result);
    verify(mockService, times(1)).someMethod();
}

private void mockIndirectDependencies() {
    // 特别注意:内部方法可能调用的外部服务
    when(externalService.getData()).thenReturn(mockData);
    when(ossService.getStorageInfo()).thenReturn(storageInfo);
    when(cacheService.get(anyString())).thenReturn(cachedValue);
}

6.4 避免UnnecessaryStubbingException

java 复制代码
// ❌ 错误:多个测试共享同一个请求对象
SearchClusterInstanceRequest searchRequest; // 成员变量

@Test
public void test1() {
   searchRequest.setClusterId("cluster-1");
   // ... 设置mock
}

@Test
public void test2() {
   searchRequest.setTags(tags); // 修改了共享对象!
   // ... 设置同样的mock,但执行路径变了
}

// ✅ 正确:每个测试使用独立对象
@Test
public void test1() {
   SearchClusterInstanceRequest request = new SearchClusterInstanceRequest();
   request.setResourceOwnerId(12345L);
   request.setClusterId("cluster-1");
   // ... 设置相应的mock
}

@Test
public void test2() {
   SearchClusterInstanceRequest request = new SearchClusterInstanceRequest();
   request.setResourceOwnerId(12345L);
   request.setTags(tags);
   // ... 设置相应的mock
}

6.4 边界条件测试清单

📝 必须覆盖的边界条件
分类 测试项 具体场景
空值处理 null参数 所有可空参数的null值处理
空集合 Collections.emptyList()、空数组
空字符串 ""、" "(空格)、null
数字边界 边界值 0、-1、1
极值 MAX_VALUE、MIN_VALUE
特殊值 NaN、Infinity(浮点数)
异常处理 预期异常 业务异常、系统异常

7. Mockito 3.x 静态Mock最佳实践

7.1 静态Mock使用场景

需要Mock的静态方法

  • 外部服务调用(如 TagHelper.validateInner* - 调用外部服务)
  • 业务逻辑验证(如 RamValidator.buildRamPermissionSpec - 构建权限规格)
  • 复杂业务判断(如 PopApiCallerType.isSubUser - 用户类型判断)
  • 单例模式的 getInstance() 方法
  • 系统时间相关(如 System.currentTimeMillis() - 需要固定时间测试)
  • 外部资源访问(如文件读写、网络请求)

不需要Mock的静态方法

  1. 纯函数工具类
java 复制代码
// 字符串工具 - 直接使用
StringUtils.isEmpty(str)
StringUtils.isBlank(str)
String.valueOf(obj)

// 数学计算 - 直接使用
Math.abs(-5)
Math.max(a, b)
Math.sqrt(16)

// 集合工具 - 直接使用
Collections.emptyList()
Collections.singletonList(item)
Arrays.asList(1, 2, 3)
  1. 简单的转换/验证方法
java 复制代码
// 类型转换 - 直接使用
Integer.valueOf("123")
Boolean.parseBoolean("true")
Double.parseDouble("3.14")
Long.parseLong("999")

// 对象工具 - 直接使用
Objects.equals(a, b)
Objects.isNull(obj)
Objects.nonNull(obj)
Objects.hash(obj1, obj2)
  1. 业务无关的工具方法
java 复制代码
// JSON序列化(如果只是日志记录)
JSON.toJSONString(obj)  // 仅用于日志时不需要mock

// 编码解码 - 直接使用
Base64.getEncoder().encode(bytes)
URLEncoder.encode(str, "UTF-8")

// 常量获取 - 直接使用
ResourceType.INSTANCE.getName()  // 枚举常量
Constants.MAX_RETRY_COUNT        // 常量值

判断原则

  • ✅ 需要Mock:有副作用、依赖外部状态、需要控制返回值
  • ❌ 不需Mock:纯函数、无副作用、结果可预测、性能开销小

7.2 Mockito 3.x配置要点

java 复制代码
// 1. 依赖版本匹配
// Mockito 3.11.2 + mockito-inline (当前项目配置)

// 2. 注解使用
@RunWith(MockitoJUnitRunner.class)  // 使用Mockito的Runner

// 3. 静态Mock的生命周期管理
public class ServiceTest {
    private MockedStatic<StaticClass> staticMock;
    
    @Before
    public void setUp() {
        MockitoAnnotations.openMocks(this);         // 初始化普通mock
        staticMock = mockStatic(StaticClass.class); // 创建静态mock
    }
    
    @After
    public void tearDown() {
        if (staticMock != null) {
            staticMock.close();  // 必须关闭,避免影响其他测试
        }
    }
}

7.3 性能优化建议

减少静态Mock使用以提升测试速度

java 复制代码
// ❌ 错误:过度使用静态Mock
@Before
public void setUp() {
    stringUtilsMock = mockStatic(StringUtils.class);     // 不需要
    collectionsMock = mockStatic(Collections.class);     // 不需要
    jsonMock = mockStatic(JSON.class);                   // 如果只是日志,不需要
    mathMock = mockStatic(Math.class);                   // 不需要
    businessServiceMock = mockStatic(BusinessService.class);  // 必要
}

// ✅ 正确:最小化静态Mock使用
@Before
public void setUp() {
    businessServiceMock = mockStatic(BusinessService.class);  // 只mock必要的业务类
}

测试性能对比(Mockito 3.x):

  • 不使用静态Mock: ~30ms/test
  • 使用MockedStatic(1个类): ~80ms/test
  • 使用MockedStatic(3个类): ~150ms/test
  • 使用MockedStatic(5+类): ~300ms/test

7.4 常见问题解决

问题 原因 解决方案
MockedStatic泄漏 未正确关闭 在@After中调用close()
静态mock不生效 MockedStatic已关闭 确保在测试期间保持打开
并发测试失败 静态mock冲突 避免并行执行使用静态mock的测试
测试运行缓慢 过度使用静态Mock 只mock必要的静态方法
内存泄漏 MockedStatic未释放 使用try-with-resources或@After关闭

7.5 从PowerMock迁移到Mockito 3.x

迁移步骤

  1. 更新依赖

    • 移除 powermock-module-junit4powermock-api-mockito2
    • 添加 mockito-inline (版本已在父pom管理)
  2. 代码迁移对照

java 复制代码
// PowerMock写法
@RunWith(PowerMockRunner.class)
@PrepareForTest({StaticClass.class})
public class OldTest {
    @Before
    public void setUp() {
        PowerMockito.mockStatic(StaticClass.class);
        when(StaticClass.method()).thenReturn(value);
    }
}

// Mockito 3.x写法
@RunWith(MockitoJUnitRunner.class)
public class NewTest {
    private MockedStatic<StaticClass> staticMock;
    
    @Before
    public void setUp() {
        staticMock = mockStatic(StaticClass.class);
        staticMock.when(StaticClass::method).thenReturn(value);
    }
    
    @After
    public void tearDown() {
        if (staticMock != null) staticMock.close();
    }
}
测试类别 测试场景 具体描述
异常处理 异常传播 异常包装和转换
逻辑分支 if/else 所有条件分支
switch 所有case分支+default
集合操作 空集合 空列表、空Map、空Set
单元素 只有一个元素的集合
多元素 正常多元素场景

七、总结

🎯 成功标准

  1. 覆盖率达标

    • ✅ 行覆盖率 > 80%
    • ✅ 分支覆盖率 > 60%
  2. 测试质量

    • ✅ 所有测试独立运行
    • ✅ Mock所有外部依赖
    • Mock间接依赖(内部方法的外部调用)
    • ✅ 覆盖所有边界条件
    • ✅ 异常场景完整测试
  3. 代码规范

    • ✅ 命名规范清晰
    • ✅ 测试结构清晰
    • ✅ 断言明确有效

⚠️ 重要提醒

测试失败时的关键检查点

  1. 检查所有直接依赖是否已mock
  2. 特别注意内部方法调用的外部依赖
  3. 检查ThreadLocal等上下文是否初始化
  4. 分析完整的方法调用链
  5. NPE通常指向未mock的外部调用
  6. UnnecessaryStubbingException通常表示测试间状态冲突或Mock未被使用
相关推荐
MaxHua23 分钟前
数据库入门指南与实战进阶-Mysql篇
后端
用户40993225021226 分钟前
FastAPI的死信队列处理机制:为何你的消息系统需要它?
后端·ai编程·trae
用户4822137167751 小时前
C++——纯虚函数、抽象类
后端
张同学的IT技术日记1 小时前
必看!用示例代码学 C++ 基础入门,快速掌握基础知识,高效提升编程能力
后端
林太白1 小时前
Nuxt3 功能篇
前端·javascript·后端
得物技术1 小时前
营销会场预览直通车实践|得物技术
后端·架构·测试
Ice__Cai2 小时前
Flask 入门详解:从零开始构建 Web 应用
后端·python·flask·数据类型
武子康2 小时前
大数据-74 Kafka 核心机制揭秘:副本同步、控制器选举与可靠性保障
大数据·后端·kafka
紫穹2 小时前
006.LangChain Prompt Template
后端
whitepure2 小时前
万字详解JavaObject类方法
java·后端