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

And*_*rle 35 unit-testing jasmine jestjs

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

onUploadStart(file, xhr, formData) {
  formData.append('filename', file.name);
  formData.append('mimeType', file.type);
}
Run Code Online (Sandbox Code Playgroud)

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

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

expect(formData.append).toHaveBeenCalledWith(
  ['mimeType', 'someMimeType'],
  ['fileName', 'someFileName']
);
Run Code Online (Sandbox Code Playgroud)

但是,断言不起作用:

Expected mock function to have been called with:
 [["mimeType", "someMimeType"], ["fileName", "someFileName"]]
But it was called with:
  ["mimeType", "someMimeType"], ["filename", "someFileName"]
Run Code Online (Sandbox Code Playgroud)

什么是正确的使用方式toHaveBeenCalledWith

And*_*ndi 75

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

expect(mockFn.mock.calls).toEqual([
  [arg1, arg2, ...], // First call
  [arg1, arg2, ...]  // Second call
]);
Run Code Online (Sandbox Code Playgroud)

mockFn你的模拟函数名称在哪里.

  • @ToniFeistauer 它已经是我们心中最好的答案 <3 (9认同)
  • 我必须使用以下语法才能使其工作:“expect(mockFn.mock.calls.allArgs()).toEqual([ ...]);”。作为参考,我使用的是 Jasmine 版本 4。 (4认同)
  • 这应该是"最佳答案" (3认同)
  • @IlyaSaunkin <3 (2认同)

Lex*_*Lex 18

您还可以toHaveBeenCalledWith对每个预期的参数组合进行多次测试和测试。

一个例子是 Google Analytics插件 api使用具有不同参数组合的相同函数调用。

function requireGoogleAnalyticsPlugins() {
  ...
  ga('create', 'UA-XXXXX-Y', 'auto');
  ga('require', 'localHitSender', {path: '/log', debug: true});
  ga('send', 'pageview');
}
Run Code Online (Sandbox Code Playgroud)

为了测试这一点,下面的示例测试了 GA 已使用各种参数组合被调用 3 次。

describe("requireGoogleAnalyticsPlugins", () => {
  it("requires plugins", () => {
    requireGoogleAnalyticsPlugins();
    expect(GoogleAnalytics.ga.toHaveBeenCalledTimes(3);
    expect(GoogleAnalytics.ga).toHaveBeenCalledWith('create', 'UA-XXXXX-Y', 'auto');
    expect(GoogleAnalytics.ga).toHaveBeenCalledWith('require', 'localHitSender', {path: '/log', debug: true});
    expect(GoogleAnalytics.ga).toHaveBeenCalledWith('send', 'pageview');
  });
});
Run Code Online (Sandbox Code Playgroud)

在 OP 情况下,您可以使用

expect(formData.append).toHaveBeenCalledWith('mimeType', 'someMimeType');
expect(formData.append).toHaveBeenCalledWith('fileName', 'someFileName');
Run Code Online (Sandbox Code Playgroud)


小智 14

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

  • 虽然此链接可能有助于您回答问题,但您可以通过获取链接的重要部分并将其放入您的答案中来改进此答案,这可确保如果链接被更改或删除,您的答案仍然是答案:) (2认同)

Eno*_*ach 11

签名是单个调用.toHaveBeenCalledWith(arg1, arg2, ...)中的arg1, arg2, ...意思(参见参考资料).

如果您想测试多个呼叫,只需expect多次.

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


Ton*_*tio 9

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

expect(mockFn.mock.calls[0][0]).toEqual('first argument');
expect(mockFn.mock.calls[0][1]).toEqual('second argument');
Run Code Online (Sandbox Code Playgroud)

我建议查看这个 Jest 备忘单:

https://devhints.io/jest


Kim*_*ern 8

您还可以为每次调用创建一个包含预期参数的数组并循环遍历它:

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

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