【问题标题】:How to match an array of objects with sinon.js?如何将对象数组与 sinon.js 匹配?
【发布时间】:2016-12-19 21:42:21
【问题描述】:

如何在 sinon 匹配器中匹配结果数组?

例如,这段代码如何工作?

var mystub = sinon.stub();
var myarg = { val: 1, mylist: [ {a:1}, {b:2}, {c:3,d:4} ] };

mystub(myarg);

sinon.assert.calledOnce(mystub).withArgs(
  sinon.match({val: 1, mylist: [{a:1},{b:2},{c:3,d:4}]}) // this doesn't work
);

我怎样才能让它工作? (请注意,在我的测试中,我无权访问 myarg - 所以我需要匹配它)。

显然,我可以编写一个自定义函数匹配器,但我正在寻找更容易读写的东西。

【问题讨论】:

    标签: javascript node.js sinon


    【解决方案1】:

    这是一篇旧帖子,但我找不到这个问题的正确答案。

    Sinon 支持嵌套匹配器。所以要测试深度对象的匹配,你可以这样做:

    const mystub = sinon.stub();
    const myarg = {
      val: 1,
      mylist: [{ a: 1, x: 'foo' }, { b: 2, y: 'bar' }, { c: 3, d: 4, e: 5 } ],
    };
    
    mystub(myarg);
    
    sinon.assert.calledOnce(mystub);
    sinon.assert.calledWithMatch(mystub, {
      val: 1,
      mylist: [
        sinon.match({ a: 1 }),
        sinon.match({ b: 2 }),
        sinon.match({ c: 3, d: 4 }),
      ],
    });
    

    【讨论】:

      【解决方案2】:

      自定义匹配器。

      我建议编写您自己的自定义 sinon matcher

      你可以用一种通用的方式来编写它,并且在使用时易于阅读。

      这是一个示例方法:

      // usage
      ...withArgs(sinon.match(deepMatch({
          val: 1,
          mylist: [{a:1}, {b:2}, {c:3,d:4}]
      })));
      
      
      // custom matcher
      const deepMatch = (expectation) => (actual) => {
          return Object.keys(expectation).every(key => {
              if (checkIfItsObject(expectation[key])) {
                  // value is also an object, go deeper and then compare etc.
              } else {
                  // compare and return boolean value accordingly
              }
          });
      };
      
      // note: checkIfItsObject is pseudocode - there are many ways to
      // check if an object is an object so I did not want to complicate
      // this code example here
      

      【讨论】:

      • 谢谢,这就是我最终要做的。似乎这将是一个共同的需求。我很惊讶它不是 sinon 的一部分。
      【解决方案3】:

      已接受答案中的自定义匹配功能有助于了解这个简单的用例,但完全是矫枉过正。以the useful answer from Eryk Warren 为基础,如何:

      // match each element of the actual array against the corresponding entry in the expected array
      sinon.assert.match(actual, expected.map(sinon.match));
      

      【讨论】:

        【解决方案4】:

        Sinon对数组的内容有匹配器,例如sinon.match.array.deepEquals

        这行得通:

        var mystub = sinon.stub();
        
        var myarg = { val: 1, mylist: [ {a:1}, {b:2}, {c:3,d:4} ] };
        
        mystub(myarg);
        
        sinon.assert.calledWith(mystub,
          sinon.match({
            val: 1,
            mylist: sinon.match.array.deepEquals([ {a:1}, {b:2}, {c:3,d:4} ])
          })
        );
        

        【讨论】:

        • 有效!就我而言,我还应该检查是否添加了新道具:sinon.assert.calledWithMatch(func, sinon.match.every(sinon.match.hasOwn('property')));
        猜你喜欢
        • 1970-01-01
        • 2022-09-22
        • 1970-01-01
        • 1970-01-01
        • 2021-11-27
        • 1970-01-01
        • 1970-01-01
        • 2017-04-12
        • 1970-01-01
        相关资源
        最近更新 更多