React测试库 - 模拟一个函数

4

我正在尝试测试一个函数是否被调用

import React from 'react';
import { render, cleanup, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom';
import MyForm from './MyForm';

afterEach(cleanup);
const testFunction = jest.fn();
test('my form', () => {
  const { getByTestId } = render(<MyForm />);
  const myButton = getByTestId('submit-button');
  expect(myButton.tagName).toBe('BUTTON');
  fireEvent.click(myButton)
  expect(testFunction).toHaveBeenCalledTimes(1)
});

我遇到的问题是似乎没有绑定到模拟函数,但它确实调用了组件中的函数。
import React from 'react';

export default function myForm() {
  function testFunction() {
    console.log('hello from inside');
  }
  return (
    <div>
      <form onSubmit={testFunction}>
        <input type="text" />
        <button type="submit" data-testid="submit-button">submit</button>
      </form>
    </div>
  );
}

如何调用模拟函数而不是“真实”函数。
expect(jest.fn()).toHaveBeenCalledTimes(1)
    
    Expected mock function to have been called one time, but it was called zero times.

你的 testFunction 是否必须(隐藏)在 myForm 组件内部?如果它是一个 prop,你可以在测试中传递它,然后模拟函数将被调用。 - tromgy
我已经见过几乎每个示例都这样做了。我将修改我的代码以适应测试。虽然我可以这样做,但这样似乎是错误的。 - TommyD
1个回答

5

你不能调用myForm的内部函数。你可以测试组件的最终可见输出,但无法测试私有功能。

这也是有道理的。单元测试应该关注其结果,而不是特定于组件内部函数是否被调用。

是的,你总是可以测试其行为。例如,你可以测试console.log是否被调用,因为它对外部世界是可见的。

同样,如果testFunction执行了其他可断言的操作,你也可以进行测试。

另一个选择是将testFunction提取出来并导出它,以便可以在任何地方使用。然后,你可以为testFunction编写单元测试,并仅测试其功能,而不是在组件单元测试的上下文中测试它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接