beforeEach 和 afterEach 是 JavaScript 测试中用于保障测试独立性的核心钩子:前者在每个测试前执行初始化(如清空 localStorage、创建新实例),后者在每个测试后执行清理(如清除 mock、恢复全局状态)。

在 JavaScript 测试中,beforeEach 和 afterEach 是最常用、最实用的两个生命周期钩子,专用于为每个测试用例自动执行“准备”和“清理”逻辑,保证测试独立、可重复、不互相污染。
什么时候该用 beforeEach
它会在每一个 test 或 it 块执行前运行一次,适合做每次测试都需要的初始化操作:
- 重置全局状态(比如清空 mock 函数调用记录、还原被修改的 window 属性)
- 创建干净的测试对象(如 new Service()、new Component())
- 模拟依赖(jest.mock() 通常放这里,确保每次都是全新 mock)
- 设置 DOM 环境(如 document.body.innerHTML = '')
- 登录或跳转到固定页面(Playwright / Cypress 中常见)
什么时候该用 afterEach
它会在每一个 test 或 it 块执行后立即运行,核心目标是“收尾”和“隔离”:
- 清除临时 DOM 节点(如移除通过 document.createElement 添加的元素)
- 恢复被修改的全局对象(如 delete window.myLib;或 restore() 所有 jest.fn().mockRestore())
- 清理 mock 数据(jest.clearAllMocks())
- 关闭打开的资源(如 WebSocket 实例、定时器 clearTimeout())
- 重置 localStorage/sessionStorage(避免影响下一个测试)
实际写法示例(Jest)
以下是一个典型组合,用于测试一个依赖 localStorage 的工具函数:
describe('userPrefs', () => {
// 每个测试前:清空 localStorage,确保干净环境
beforeEach(() => {
localStorage.clear();
});
// 每个测试后:再次确认清空(防御性写法),并清除所有 mock
afterEach(() => {
localStorage.clear();
jest.clearAllMocks();
});
test('saves theme to localStorage', () => {
saveTheme('dark');
expect(localStorage.getItem('theme')).toBe('dark');
});
test('loads default theme when not set', () => {
expect(loadTheme()).toBe('light');
});
});
注意事项与避坑点
这几个细节容易被忽略,但直接影响测试稳定性:
- 钩子函数内部不要用 async/await 除非返回 Promise(Jest 会自动等待)
- 不要在 beforeEach 里做耗时操作(如启动服务器),应改用 beforeAll
- 避免在 afterEach 中 throw 错误——它不会让测试失败,但可能掩盖真实问题
- 多个 describe 嵌套时,钩子按层级顺序执行:外层 beforeEach → 内层 beforeEach → test → 内层 afterEach → 外层 afterEach
- 如果某个测试需要跳过清理(极少数场景),可在 afterEach 中加条件判断,但需谨慎











