You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Jest测试JavaScript函数是否存在副作用

Jest 通用无副作用检测测试实现

核心检测逻辑完全通用,不绑定特定函数或特定类型入参,核心思路很简单:调用函数前留存所有入参的深拷贝快照,函数执行完成后,逐一比对实际传入的参数和原始快照是否完全一致,不一致就说明函数修改了入参、存在副作用。

完整的测试文件代码如下:

import myFunction from "./myFunction.js";

/**
 * 通用无副作用校验工具
 * @param {Function} fn 待测函数
 * @param  {...any} args 传入待测函数的任意数量、任意类型参数
 * @returns 待测函数的返回值
 */
function assertNoSideEffects(fn, ...args) {
  // 对所有入参做深拷贝,留存原始状态快照
  const originalSnapshots = args.map(arg => structuredClone(arg));
  // 正常执行待测函数
  const result = fn(...args);
  // 逐个校验入参:执行后状态必须和原始快照完全一致
  args.forEach((actualArg, idx) => {
    expect(actualArg).toEqual(originalSnapshots[idx]);
  });
  return result;
}

test("that there are no side-effects", () => {
  // 自定义你的测试入参即可
  const myArray = [1, 2, { test: "嵌套值" }, 4];
  // 传入待测函数和对应入参,自动完成副作用校验
  assertNoSideEffects(myFunction, myArray);
});

方案说明

  • 适配所有场景:不管待测函数接收多少个参数,参数是数组、嵌套对象、Map/Set/Date等特殊类型,还是基础类型值,只要按顺序把参数传给assertNoSideEffects即可,不需要为每个用例单独写比对逻辑
  • 深拷贝实现采用原生structuredClone,Node 17+、所有现代测试环境默认支持,比JSON.parse(JSON.stringify())支持的数据类型更全;如果你的环境版本过低,可以替换为lodash的_.cloneDeep,比对逻辑不需要任何修改
  • 校验逻辑和函数返回值完全解耦:不管待测函数有没有返回值、返回什么内容,都不会干扰入参是否被篡改的检测结果
  • 不影响Jest其他能力:如果需要用jest.spyOn模拟函数内部依赖、做返回值断言等,都可以正常写,和普通测试用例写法没有区别

内容的提问来源于stack exchange,提问作者Rolazar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 04:51:21