如何用 sinon.js 匹配一个对象数组?

How to match an array of objects with sinon.js?

如何在 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 - 所以我需要匹配它)。

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

自定义匹配器。

我建议编写您自己的自定义 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 支持嵌套匹配器。因此,要测试深层对象的匹配,您可以执行以下操作:

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 }),
  ],
});

接受的答案中的自定义匹配功能对于了解这个简单的用例来说很有用,但总的来说有点矫枉过正。要以 为基础,这个怎么样:

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

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} ])
  })
);