如何使用 toHaveBeenCalledWith 检查匿名函数的函数参数?

Man*_*n J 12 jestjs enzyme

我想测试一个函数,它只返回一个带有一些值的函数和一个匿名函数作为参数。如何在玩笑中使用 toHaveBeenCalledWith 测试匿名函数的匹配?

function toBeTested( id, values) {
 return xyz(id, values, () => {
  return { 
    type: 'foo', 
    payload: { 
     text: values.text
    }
  }
 })
}
Run Code Online (Sandbox Code Playgroud)

在我的测试中

describe('test for toBeTested',  () => {
  it('should call xyz with params', () => {
    const id = 123;
    const values = {
      text: 'Hello world',
    };

   xyz = jest.fn();
   toBeTested(id, values);
    expect(xyz).toHaveBeenCalledWith(id, values, () => {
     return {
      type: 'foo',
      payload: {
       text: values.text,
      }
     }
    });
  })
})
Run Code Online (Sandbox Code Playgroud)

测试错误报告

 expect(jest.fn()).toHaveBeenCalledWith(expected)

    Expected mock function to have been called with:
      [123, {text: 'Hello world'}, [Function anonymous]]
    But it was called with:
      [123, {text: 'Hello world'}, [Function anonymous]]

      at Object.it.only (src/actions/tests/xyz.test.js:30:43)
          at new Promise (<anonymous>)
      at Promise.resolve.then.el (node_modules/p-map/index.js:46:16)
          at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:188:7)
Run Code Online (Sandbox Code Playgroud)

小智 21

我遇到了同样的问题,我发现这个问题所选的答案对我没有帮助。所以我决定写一个解决我问题的答案,希望它可以帮助其他人。

TL;DR:使用expect.any(Function)如下:

    expect(xyz).toHaveBeenCalledWith(
      id,
      values,
      expect.any(Function)
    );
Run Code Online (Sandbox Code Playgroud)

完整答案:

所选答案确实是您可以接收回调的情况的替代方案,但是在其他情况下,匿名函数不应公开,甚至不应由调用者函数提供。

例子:

import { exec } from 'child_process';

export const runScript = (data: string): Promise<string> => {
  return new Promise((resolve, reject) => {
    exec(`a script to be called with this data ${data}`, (error) => {
      if (error) {
        // handle error
        // ...
        reject();
      } else {
        // do something
        // ...
        resolve('result');
      }
    });
  });
};
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,我不想接收错误处理函数作为回调,因为该逻辑实际上是该函数固有的runScript,并且不应该由外部调用者函数实现或提供。真正的函数会包含更多逻辑,但我相信共享其结构已经给出了这些场景存在的想法。

注意:// ...我的代码中的部分有更多的逻辑,调用外部函数,我可以模拟并断言传递给它们的内容,这样我就可以正确测试它。我只是为了简化而删除了它

不管怎样,我是这样测试的:

expect(execMock).toHaveBeenCalledWith(
  '...',
  expect.any(Function),
);

Run Code Online (Sandbox Code Playgroud)

在你的情况@manikandan-j,它将是:


it('should call xyz with params', () => {
    const id = 123;
    const values = {
      text: 'Hello world',
    };

    xyz = jest.fn();
    toBeTested(id, values);
    expect(xyz).toHaveBeenCalledWith(
      id,
      values,
      expect.any(Function)
    );
  });
});
Run Code Online (Sandbox Code Playgroud)

另外,如果您使用expect.any(Function)(正如我正在使用的)并且您想测试匿名函数的内容

() => {
  return { 
    type: 'foo', 
    payload: { 
    text: values.text
  }
}
Run Code Online (Sandbox Code Playgroud)

您将测试结果是否toBeTested会受到这些值的影响。像下面这样:

    const result = toBeTested(id, values);
    expect(xyz).toHaveBeenCalledWith(
      id,
      values,
      expect.any(Function)
    );
    expect(result).toBe(...);
Run Code Online (Sandbox Code Playgroud)

无论如何,我希望它可以帮助人们测试其参数之一是无法作为参数接收的匿名函数的函数。