news 2026/7/8 7:54:00

JUnit4测试生命周期

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JUnit4测试生命周期

JUnit4 测试生命周期详解

概述

理解JUnit4测试生命周期是编写有效单元测试的关键。本文件详细说明测试的执行流程、实例化策略、注解执行顺序等核心概念。

1. 测试生命周期总览

完整的测试执行流程图

┌─────────────────────────────────────────────────────┐
│ 测试类加载 │
├─────────────────────────────────────────────────────┤
│ @BeforeClass 方法执行 │
│ (整个类生命周期只执行一次) │
├─────────────────────────────────────────────────────┤
│ │
│ 对于每个@Test方法: │
│ ┌─────────────────────────────────────────────┐ │
│ │创建新的测试实例│ │
│ ├─────────────────────────────────────────────┤ │
│ │ @Before 方法执行 │ │
│ ├─────────────────────────────────────────────┤ │
│ │ @Test 方法执行 │ │
│ ├─────────────────────────────────────────────┤ │
│ │ 可能执行:@Test(expected) │ │
│ │ 可能执行:@Test(timeout) │ │
│ ├─────────────────────────────────────────────┤ │
│ │ @After 方法执行 │ │
│ │ (即使@Test抛出异常也会执行) │ │
│ └─────────────────────────────────────────────┘ │
│ │
├─────────────────────────────────────────────────────┤
│ @AfterClass 方法执行 │
│ (整个类生命周期只执行一次) │
└─────────────────────────────────────────────────────┘

2. 测试类实例化策略

2.1 默认行为:每个测试方法一个实例

JUnit4默认情况下为每个@Test方法创建新的测试实例

importorg.junit.Before;importorg.junit.Test;importstaticorg.junit.Assert.*;publicclassTestInstancePerMethodTest{privateintinstanceCounter=0;publicTestInstancePerMethodTest(){System.out.println("构造函数被调用,创建新实例");instanceCounter=0;// 每次创建新实例时重置}@BeforepublicvoidsetUp(){instanceCounter++;System.out.println("setUp() 执行,instanceCounter: "+instanceCounter);}@TestpublicvoidtestMethod1(){System.out.println("testMethod1 执行,instanceCounter: "+instanceCounter);// 这个实例的instanceCounter是1assertEquals(1,instanceCounter);}@TestpublicvoidtestMethod2(){System.out.println("testMethod2 执行,instanceCounter: "+instanceCounter);// 新的实例,所以instanceCounter也是1assertEquals(1,instanceCounter);}}/* 输出示例: 构造函数被调用,创建新实例 setUp() 执行,instanceCounter: 1 testMethod1 执行,instanceCounter: 1 构造函数被调用,创建新实例 setUp() 执行,instanceCounter: 1 testMethod2 执行,instanceCounter: 1 */

2.2 验证不同实例

publicclassDifferentInstancesTest{privateintinstanceId=(int)(Math.random()*1000);@TestpublicvoidtestInstance1(){System.out.println("testInstance1 - instanceId: "+instanceId);// 保存当前实例IDintcurrentId=instanceId;// 修改实例变量instanceId=999;// 验证修改只影响当前实例assertEquals(999,instanceId);// 在其他测试中这个修改不会生效}@TestpublicvoidtestInstance2(){System.out.println("testInstance2 - instanceId: "+instanceId);// 这是一个新的实例,所以instanceId是新的随机值// 不是999!assertNotEquals(999,instanceId);}}

2.3 为什么每个测试方法创建新实例?

设计目的

  1. 测试隔离:确保测试之间不会相互影响

  2. 线程安全:每个测试在独立的实例上运行

  3. 状态重置:避免测试间的状态污染

3. 注解执行顺序详解

3.1 完整的执行顺序

BeforeClass>{构造函数>Before>Test>After} * N>AfterClass

importorg.junit.*;publicclassFullLifecycleTest{// ===== 类级别生命周期 =====@BeforeClasspublicstaticvoidbeforeClass(){System.out.println("1. @BeforeClass - 类级别初始化");}@AfterClasspublicstaticvoidafterClass(){System.out.println("9. @AfterClass - 类级别清理");}// ===== 实例级别生命周期 =====@Beforepublicvoidbefore(){System.out.println(" 3. @Before - 测试方法前执行");}@Afterpublicvoidafter(){System.out.println(" 5. @After - 测试方法后执行");}// ===== 测试方法 =====@TestpublicvoidtestOne(){System.out.println(" 4. @Test testOne 执行");}@TestpublicvoidtestTwo(){System.out.println(" 4. @Test testTwo 执行");}// ===== 构造函数 =====publicFullLifecycleTest(){System.out.println("2. 构造函数 - 创建测试实例");}}/** * 1. @BeforeClass - 类级别初始化 * 2. 构造函数 - 创建测试实例 * 3. @Before - 测试方法前执行 * 4. @Test testOne 执行 * 5. @After - 测试方法后执行 * 2. 构造函数 - 创建测试实例 * 3. @Before - 测试方法前执行 * 4. @Test testTwo 执行 * 5. @After - 测试方法后执行 * 9. @AfterClass - 类级别清理 */

3.2 异常情况下的生命周期

场景1:@Before抛出异常

@Before异常了,@After还是会执行的,只不过@Test不会执行了

publicclassExceptionInBeforeTest{@BeforepublicvoidsetUp(){System.out.println("@Before 执行");thrownewRuntimeException("@Before 中发生异常");}@AfterpublicvoidtearDown(){System.out.println("@After 执行");}@TestpublicvoidtestMethod(){System.out.println("测试方法执行");fail("这个测试不应该执行");}}/* 输出: @Before 执行 @After 执行 结果:测试失败,@Test方法不会执行,但@After仍然执行 */
场景2:@Test抛出异常

即使@Test报错了,@After还是会执行的

publicclassExceptionInTestTest{@BeforepublicvoidsetUp(){System.out.println("@Before 执行");}@AfterpublicvoidtearDown(){System.out.println("@After 执行(即使@Test抛出异常)");}@Test(expected=RuntimeException.class)publicvoidtestWithExpectedException(){System.out.println("抛出期望的异常");thrownewRuntimeException("测试异常");}@TestpublicvoidtestWithUnexpectedException(){System.out.println("抛出未期望的异常");thrownewRuntimeException("意外异常");}}/* 第一个测试输出: @Before 执行 抛出期望的异常 @After 执行(即使@Test抛出异常) 结果:测试通过(因为异常符合expected) 第二个测试输出: @Before 执行 抛出未期望的异常 @After 执行(即使@Test抛出异常) 结果:测试失败(未期望的异常) */
场景3:@After抛出异常
publicclassExceptionInAfterTest{@TestpublicvoidtestSuccess(){System.out.println("测试成功执行");}@TestpublicvoidtestFailure(){System.out.println("测试失败执行");fail(<
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/7 8:23:18

3分钟掌握Easy-Scraper:零基础网页数据抓取神器

还在为复杂的数据抓取任务而头疼吗&#xff1f;传统爬虫工具需要掌握繁琐的CSS选择器或XPath语法&#xff0c;让无数新手望而却步。今天&#xff0c;让我们一起探索Easy-Scraper——这款革命性的网页抓取工具&#xff0c;用最简单的方式帮你获取所需数据&#xff01;Easy-Scrap…

作者头像 李华
网站建设 2026/7/7 13:35:36

飞书文档批量导出终极指南:告别手动烦恼,实现高效迁移

飞书文档批量导出终极指南&#xff1a;告别手动烦恼&#xff0c;实现高效迁移 【免费下载链接】feishu-doc-export 项目地址: https://gitcode.com/gh_mirrors/fe/feishu-doc-export 你是否曾经为文档迁移而头疼不已&#xff1f;面对数百个飞书文档需要导出到本地&…

作者头像 李华
网站建设 2026/7/7 1:13:12

SuperCom串口调试工具:终极免费解决方案与5分钟快速部署指南

想要摆脱串口调试的繁琐操作吗&#xff1f;SuperCom作为一款功能强大的免费串口调试工具&#xff0c;专为嵌入式开发者和硬件工程师设计&#xff0c;让你在5分钟内完成从零开始的完整配置。无论是多设备并行监控还是自动化命令执行&#xff0c;这款工具都能显著提升你的工作效率…

作者头像 李华
网站建设 2026/7/7 10:28:39

Vulkan显存检测利器:memtest_vulkan快速验证显卡稳定性

Vulkan显存检测利器&#xff1a;memtest_vulkan快速验证显卡稳定性 【免费下载链接】memtest_vulkan Vulkan compute tool for testing video memory stability 项目地址: https://gitcode.com/gh_mirrors/me/memtest_vulkan 显卡性能不稳定导致游戏闪退、画面异常&…

作者头像 李华
网站建设 2026/7/8 2:38:24

揭秘BlenderGIS:5分钟搞定专业级地形生成的秘密武器

揭秘BlenderGIS&#xff1a;5分钟搞定专业级地形生成的秘密武器 【免费下载链接】BlenderGIS Blender addons to make the bridge between Blender and geographic data 项目地址: https://gitcode.com/gh_mirrors/bl/BlenderGIS 还在为手动创建3D地形而头疼吗&#xff…

作者头像 李华
网站建设 2026/7/7 8:25:08

终极Mac桌面歌词神器LyricsX完整使用指南

终极Mac桌面歌词神器LyricsX完整使用指南 【免费下载链接】Lyrics Swift-based iTunes plug-in to display lyrics on the desktop. 项目地址: https://gitcode.com/gh_mirrors/lyr/Lyrics 还在为Mac音乐播放器缺乏歌词显示功能而烦恼吗&#xff1f;LyricsX桌面歌词插件…

作者头像 李华