javascript - JavaScript 数组克隆相等断言中的奇怪行为

标签 javascript arrays unit-testing mocha.js chai

我在 JavaScript 单元测试中发现了一个失败的断言,我想修复它。单元测试代码如下(完整代码可见here):

    beforeEach(function() {
      arrNeedle = ['waffles'];
      objNeedle = {w: 'waffles'};
      strNeedle = 'waffles';
      numNeedle = 3.14159

      arrDupe = JSON.parse(JSON.stringify(arrNeedle));
      objDupe = JSON.parse(JSON.stringify(objNeedle));
      strDupe = JSON.parse(JSON.stringify(strNeedle));
      numDupe = JSON.parse(JSON.stringify(numNeedle));

      arrContainer = [arrDupe, objDupe, strDupe, numDupe];
      objContainer = {
        arr: arrDupe
        , obj: objDupe
        , str: strDupe
        , num: numDupe
      };

      arrMissing = ['chan'];
      objMissing = {missing: 'chan'}
      strMissing = 'chan';

    });

    it("has its test set up correctly", function() {
      arrNeedle.should.not.equal(arrDupe);
      objNeedle.should.not.equal(objDupe);

      arrContainer.should.not.contain(arrNeedle);
      arrContainer.should.not.contain(objNeedle); // fails

      objContainer.arr.should.not.equal(arrNeedle);
      objContainer.obj.should.not.equal(objNeedle);
    });

在测试中,我们克隆一个对象并将其插入到数组中:

objNeedle = {w: 'waffles'}; // original
objDupe = JSON.parse(JSON.stringify(objNeedle)); // clone
arrContainer = [arrDupe, objDupe, strDupe, numDupe]; // add clone to array

失败的断言检查数组(包含克隆对象)是否不包含原始对象。

arrContainer.should.not.contain(objNeedle); // fails

我尝试使用外部断言插入(chai-things),但没有成功:

arrContainer.should.not.include(objNeedle); // fails
arrContainer.should.not.include.something.that.deep.equals(objNeedle); // fails

以下断言通过了测试,但不是理想的解决方案:

arrContainer[0].should.not.equal(objNeedle); // pass

您知道为什么仅在某些情况下才将数组视为等于其克隆吗?

提前致谢:)

最佳答案

如果你看一下 ChaiJS 代码,你会看到 line 189 of /lib/chai/core/assertions.js以下内容:

if (_.type(obj) === 'array' && _.type(val) === 'object') {
  for (var i in obj) {
    if (_.eql(obj[i], val)) {
      expected = true;
      break;
    }
  }
}

它位于 include(val, msg) 函数内,这是 .contains() 匹配器使用的内容(请参阅 line 215 )。

这意味着如果obj(被测试的东西)是一个数组,并且val(.contains()的参数) matcher function) 是一个对象,就像您的情况一样,它将使用 _.eql() 检查深度相等性(_.eql 是由外部 deep-eql 模块提供/导出的函数)。

关于javascript - JavaScript 数组克隆相等断言中的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28956295/

相关文章:

javascript - 在不刷新页面的情况下删除 URL 参数

javascript - 扩展/覆盖 jQuery 对象文字方法 - 超出范围问题

arrays - 数组中最远的小元素

c# - 如何测试具有大量依赖项的代码

java - 单元测试用例 MockRestServiceServer 预期的 url 不适用于 RestTemplate

java - 如何对扩展/继承第 3 方类的类进行单元测试

javascript - Express.js 'socket.io/socket.io.js 404'

PHP AJAX 文件上传

javascript - 如何让 javascript 计时器在不查看选项卡/窗口时停止

javascript - 复制数组上的拼接会从父/主数组中删除对象