Mocha单元测试中执行副作用函数后数组值未变更问题
Mocha单元测试中filterOut函数未修改原数组导致断言失败
问题核心
你的filterOut函数内部通过filter方法得到了正确的过滤结果,但原数组并未被修改,导致测试断言失败。这是因为Array.filter()返回的是新数组,而你在函数内只是重新赋值了局部参数变量,并没有修改外部传入的原数组引用。
修复方案
方案1:让filterOut返回过滤后的数组(推荐)
修改filterOut函数,返回处理后的新数组,测试时断言返回值而非原数组:
修正后的Filter类代码
filterOut(toFilterOut: Array<string>): Array<string> { let filtered = [...toFilterOut]; // 复制原数组,避免修改原数组 this.filterCallbacks.forEach(callback => { filtered = filtered.filter(el => callback(el)); }); console.log("filtered out:", filtered); return filtered; }
修正后的测试代码
import 'mocha'; import { expect } from "chai"; import Filter from "../src/Filter"; let filter = new Filter("Websites Filter"); describe("Filter", function () { describe("filterOut", () => { it("Should return array as specified conditions says", function () { const png_jpg_filter = function(el){ return !el.endsWith(".png") && !el.endsWith(".jpg"); }; filter.addFilter("png_jpg_filter", png_jpg_filter); const arrToFilter = [".png", ".jpg", ".gif"]; const result = filter.filterOut(arrToFilter); // 接收返回的结果 expect(result).to.deep.equal([".gif"]); // 用deep.equal断言数组内容 }); }); });
方案2:直接修改原数组(不推荐,易产生副作用)
如果一定要修改传入的原数组,可以用splice替换原数组的所有元素:
修正后的filterOut函数
filterOut(toFilterOut: Array<string>): void { let filtered = [...toFilterOut]; this.filterCallbacks.forEach(callback => { filtered = filtered.filter(el => callback(el)); }); // 替换原数组的全部内容 toFilterOut.splice(0, toFilterOut.length, ...filtered); console.log("filtered out:", toFilterOut); }
测试代码无需修改断言,但这种方式会直接改变原数组,可能在其他业务场景引发意外问题。
关键说明
- Array.filter()特性:
filter方法不会修改原数组,始终返回包含符合条件元素的新数组。 - 参数传递机制:TS/JS中引用类型的参数是按值传递的——你修改的是参数变量的引用,而非原数组本身,重新赋值参数不会影响外部的原数组。
- 数组断言方式:Chai中
equals是比较数组引用是否相同,需用deep.equal来对比数组的内容是否一致。
内容的提问来源于stack exchange,提问作者M-Zoldak
相关产品推荐
相关产品推荐

