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

为何被测的addSale()函数会修改测试文件中的测试数据对象?

为何被测的addSale()函数会修改测试文件中的测试数据对象?

这其实是JavaScript/TypeScript里对象引用传递的经典“坑”,我给你掰碎了说:

核心原因:对象是引用类型,不是值类型

你在测试文件里定义的standardSalesHistoryPintje是一个SalesHistory对象,属于引用类型。当你用Object.defineProperty把它赋值给salesHistoryService.salesHistories时,并不是把这个对象完整复制了一份过去,而是把它在内存中的“地址”传给了服务里的数组。换句话说:

  • 测试文件里的standardSalesHistoryPintje
  • 服务salesHistories数组里的那个SalesHistory项
    这两个变量其实指向的是内存中同一个对象,就像两个人拿着同一把钥匙开同一个箱子。

看addSale()里的操作是怎么修改原对象的

当你调用addSale()时,代码里会执行:

let salesHistory: SalesHistory = this.salesHistories.find(salesHistory => salesHistory.name === this.generalService.capitalizeFirstLetter(name));
// ...
salesHistory.sales.push(sale);

这里的salesHistory就是从数组里找到的那个和standardSalesHistoryPintje同地址的对象。salesHistory.sales.push(sale)直接修改了这个对象的sales数组——既然是同一个对象,测试文件里的standardSalesHistoryPintje.sales自然也会跟着增加新的sale项,因为它们本来就是同一个东西。

为什么移到beforeEach就好了?

当你把standardSalesHistoryPintje的定义移到beforeEach里后,每次测试执行前都会重新创建一个全新的对象。也就是说,每个测试用的都是独立的“箱子”,它们的内存地址完全不同。哪怕某个测试修改了当前的对象,也不会影响其他测试的对象,自然就不会出现测试污染了。

再补个小总结

  • 像数字、字符串这种值类型,变量存的是具体的值,赋值时会完整复制;
  • 像对象、数组这种引用类型,变量存的是内存地址,赋值时传递的是地址,多个变量会指向同一个对象;
  • 写测试时,共享的引用类型测试数据很容易导致交叉污染,最好每次测试都创建全新的实例。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 11:53:09