如何使用Chai按值而非类型比较数组(含Float32Array示例)
Chai中按值比较不同类型数组的方法
我完全懂你的需求——不用纠结数组的具体类型,只验证它们包含的数值是否一致对吧?Chai默认的assert.deepEqual和assert.sameMembers都会严格校验对象类型,所以直接对比Float32Array和普通数组肯定会失败。这里有几个实用的解决方案:
方法1:手动转换TypedArray为普通数组(最简单直接)
既然问题出在类型不匹配,那我们可以先把Float32Array转换成普通数组再做对比,用Array.from()或者扩展运算符[...]都可以:
const assert = chai.assert; function test(fn) { try { fn(); console.log('pass:'); } catch (e) { console.log('fail:', e.stack.split('\n')[0]); } } // 修改后的测试用例 test(() => assert.deepEqual([1,2,3], [1,2,3])); test(() => assert.deepEqual(Array.from(new Float32Array([1,2,3])), [1,2,3])); // 转换后对比 test(() => assert.sameMembers([...new Float32Array([1,2,3])], [1,2,3])); // 扩展运算符转换
这个方法的好处是不用修改Chai的默认行为,适合零散的测试场景。
方法2:自定义断言函数(适合频繁使用的场景)
如果你需要多次做这种值对比,可以给Chai扩展一个自定义的断言方法,比如valuesEqual,让它自动处理TypedArray和普通数组的对比:
const assert = chai.assert; // 扩展Chai的assert对象 assert.valuesEqual = function(actual, expected, message) { // 处理TypedArray,转换为普通数组 const normalize = (arr) => { if (ArrayBuffer.isView(arr)) { return Array.from(arr); } return arr; }; const normalizedActual = normalize(actual); const normalizedExpected = normalize(expected); // 用deepEqual做值对比 assert.deepEqual(normalizedActual, normalizedExpected, message); }; // 测试自定义断言 function test(fn) { try { fn(); console.log('pass:'); } catch (e) { console.log('fail:', e.stack.split('\n')[0]); } } test(() => assert.valuesEqual(new Float32Array([1,2,3]), [1,2,3])); test(() => assert.valuesEqual([1,2,3], new Float32Array([1,2,3]))); test(() => assert.valuesEqual(new Uint8Array([0,255]), [0,255]));
这样之后,你就可以在任何测试里直接用assert.valuesEqual来做值对比,不用每次手动转换了。
方法3:修改Chai的默认deepEqual配置(全局生效)
如果你希望所有的deepEqual都忽略TypedArray和普通数组的类型差异,只对比值,可以修改Chai的全局配置:
chai.config.deepEqual = function(actual, expected) { // 如果其中一个是TypedArray,另一个是数组,转换后再对比 if (ArrayBuffer.isView(actual) && Array.isArray(expected)) { return chai.util.deepEqual(Array.from(actual), expected); } if (Array.isArray(actual) && ArrayBuffer.isView(expected)) { return chai.util.deepEqual(actual, Array.from(expected)); } // 其他情况用默认的deepEqual逻辑 return chai.util.deepEqual(actual, expected); }; const assert = chai.assert; function test(fn) { try { fn(); console.log('pass:'); } catch (e) { console.log('fail:', e.stack.split('\n')[0]); } } // 现在直接用deepEqual就能通过了 test(() => assert.deepEqual(new Float32Array([1,2,3]), [1,2,3]));
这个方法会全局改变Chai的deepEqual行为,适合整个项目都需要这种值对比的场景。
内容的提问来源于stack exchange,提问作者user128511
相关产品推荐
相关产品推荐

