如何检查多个调用间谍的多个参数?

时间:2016-10-13 10:15:31

标签: unit-testing jasmine jestjs

我在React组件中有以下功能:

onUploadStart(file, xhr, formData) {
  formData.append('filename', file.name);
  formData.append('mimeType', file.type);
}

这是我的测试,至少可以调用间谍:

const formData = { append: jest.fn() };
const file = { name: 'someFileName', type: 'someMimeType' };
eventHandlers.onUploadStart(file, null, formData);

expect(formData.append).toHaveBeenCalledWith(
  ['mimeType', 'someMimeType'],
  ['fileName', 'someFileName']
);

然而,断言无效:

Expected mock function to have been called with:
 [["mimeType", "someMimeType"], ["fileName", "someFileName"]]
But it was called with:
  ["mimeType", "someMimeType"], ["filename", "someFileName"]

使用toHaveBeenCalledWith的正确方法是什么?

7 个答案:

答案 0 :(得分:56)

我能够模拟多个调用并以这种方式检查参数:

expect(mockFn.mock.calls).toEqual([
  [arg1, arg2, ...], // First call
  [arg1, arg2, ...]  // Second call
]);

其中mockFn是您的模拟函数名称。

答案 1 :(得分:8)

签名为.toHaveBeenCalledWith(arg1, arg2, ...),其中arg1, arg2, ...表示电话(see)。

如果您想测试多个来电,只需多次expect

不幸的是,我还没有找到一种测试多次调用顺序的方法。

答案 2 :(得分:6)

自开玩笑23.0起,.toHaveBeenNthCalledWith(nthCall, arg1, arg2, ....) https://facebook.github.io/jest/docs/en/expect.html#tohavebeennthcalledwithnthcall-arg1-arg2-

答案 3 :(得分:2)

您还可以测试toHaveBeenCalledWith,并为每种预期的参数组合测试多次。

下面的示例测试了GA被调用了三次,包括三个必需的插件。

  describe("requireDefaultGoogleAnalyticsPlugins", () => {
    it("requires defualt plugins", () => {
      requireDefaultGoogleAnalyticsPlugins(TRACKER);
      expect(GoogleAnalytics.analytics).toHaveBeenCalledTimes(3);
      expect(GoogleAnalytics.analytics).toHaveBeenCalledWith(
        `${TRACKER}.require`, "linkid", "linkid.js"
      );
      expect(GoogleAnalytics.analytics).toHaveBeenCalledWith(
        `${TRACKER}.require`, "displayfeatures"
      );
      expect(GoogleAnalytics.analytics).toHaveBeenCalledWith(
        `${TRACKER}.require`, "ec"
      );
    });
  });

在OP中,您可以使用

进行测试
expect(formData.append).toHaveBeenCalledWith('mimeType', 'someMimeType');
expect(formData.append).toHaveBeenCalledWith('fileName', 'someFileName');

答案 4 :(得分:1)

您还可以为每个调用创建一个预期参数数组,并在其上循环:

const expectedArgs = ['a', 'b', 'c', 'd']
expectedArgs.forEach((arg, index) => 
    expect(myFunc).toHaveBeenNthCalledWith(index + 1, arg))

此解决方案考虑了呼叫的顺序。如果您不关心顺序,则可以使用不带索引的toHaveBeenCalledWith

答案 5 :(得分:0)

这也适用于我...初始页面加载执行默认搜索...用户交互和点击搜索执行另一次搜索...验证搜索过程需要正确地增加搜索值...

let model = {
        addressLine1: null,
        addressLine2: null,
        city: null,
        country: "US"};
let caModel = { ...model, country: "CA" };
const searchSpy = props.patientActions.searchPatient;
expect(searchSpy.mock.calls).toEqual([[{ ...model }], [{ ...caModel }]]);

答案 6 :(得分:0)

另一种基于安迪的解决方案。选择所需的调用,然后检查参数的值。在此示例中,选择了第一个呼叫:

expect(mockFn.mock.calls[0][0]).toEqual('first argument');
expect(mockFn.mock.calls[0][1]).toEqual('second argument');

我建议您查看这份Jest速查表:

https://devhints.io/jest