期望 jest mock 在 react 测试库中被调用时参数失败

Expect jest mock to have been called with an argument fails in react testing library

我希望这个测试能通过,但它失败了:

it('should consume files on drop', () => {
  const mock = jest.fn();
  const file = new File(['file'], 'file.txt', { type: 'text/plain' });
  const fileList = [file];

  render(<DropZone onDocumentDrop={mock} />);

  const dropZone = screen.getByTestId('dropZone');
  const dropEvent = createEvent.drop(dropZone);

  Object.defineProperty(dropEvent, 'dataTransfer', {
    value: {
      files: {
        item: (index: number) => fileList[index],
        length: fileList.length,
      },
    },
  });

  fireEvent(dropZone, dropEvent);

  expect(dropZone).toBeInTheDocument();
  expect(mock).toHaveBeenCalled();
  expect(mock).toHaveBeenCalledWith({
    item: (index: number) => fileList[index],
    length: 1,
  });
});

Jest 报告说:

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

- Expected
+ Received

- {"item": [Function item], "length": 1},
+ {"item": [Function item], "length": 1},

我不确定如何让它通过或进一步了解问题所在?

javascript 中的两个不同对象不是相同的值,即使它们具有相同的 key/value 对 - 一个对象作为引用存储在内存中,因此两个不同的对象有两个不同的值引用,因此它们不相等。

尝试一次定义对象并传递它的引用:

const files = {
    item: (index: number) => fileList[index],
    length: fileList.length,
};

Object.defineProperty(dropEvent, 'dataTransfer', { value: { files, }, });
// -- snip --- //
expect(mock).toHaveBeenCalledWith(files);

检查最后一个函数调用的参数时,可以使用expect.objectContaining()来匹配接收到的对象。

您也可以使用 lastCalledWith() 代替 toHaveBeenCalledWith()。它们是相同的,但我个人更喜欢前者,因为它更短且更易于阅读。

const item = (index: number) => []
const args = {
  length: 1,
  item,
}

const mock = jest.fn()

mock(args)

expect(mock).lastCalledWith(
  expect.objectContaining({
    length: expect.any(Number), // or 1 if you know the exact value
    item: expect.any(Function),
  })
)