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

如何使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:38:23