测试点击处理程序内部的函数-Jest,React测试库



我有一个按钮点击处理程序,我在其中调用另一个函数。我需要测试处理程序内部的函数调用:

SomeComponent

...
const handler = () => {
someFunction();
}
...
<button data-testId="button" onClick={handler}>Click Me</button>

测试

describe('Button click', () => {
it('button click', async () => {
render(<SomeComponent />);
const button = await screen.findByTestId('button');
fireEvent.click(button);
// some silly test case just for example
expect(button).toBeInTheDocument();
});
});

在执行此操作时,它涵盖了处理程序,但不涵盖内部函数本身:

const handler = () => { <<<<<<< covered
someFunction();       <<<<<<< UNCOVERED
}.                      <<<<<<< covered

这里的主要问题是如何测试内部函数调用?如果我需要模拟它,我应该怎么做,因为模拟的函数不会测试实际的函数?

更新

此外,我的someFunction不会更改该组件范围内的任何内容,因此我无法通过比较内部状态或文档更改来捕获它。

SomeFunction来自另一个文件,我单独测试了它。

这取决于someFunction的定义位置。如果它是<SomeComponent />的一个属性,那么你可以这样做:

describe('Button click', () => {
it('button click', async () => {
const someFunction = jest.fn();
render(<SomeComponent someFunction={someFunction} />);
const button = await screen.findByTestId('button');
fireEvent.click(button);
// if there are some precise arguments given to `someFunction` maybe 
// use `toHaveBeenCalledWith` instead
expect(someFunction).toHaveBeenCalled();
});
});

但是,如果它是在一个单独的钩子中定义的,那么您应该模拟这个钩子。例如,这里假设有一个useSomeFunction直接返回这个someFunction:

import { useSomeFunction  } from '../path/to/useSomeFunction';
jest.mock('../path/to/useSomeFunction', () => ({
useSomeFunction: jest.fn(),
}));
describe('Button click', () => {
it('button click', async () => {
const mockSomeFunction = jest.fn();
useSomeFunction.mockImplementation(() => mockSomeFunction);
render(<SomeComponent />);
const button = await screen.findByTestId('button');
fireEvent.click(button);
// if there are some precise arguments given to `someFunction` maybe 
// use `toHaveBeenCalledWith` instead
expect(mockSomeFunction).toHaveBeenCalled();
});
});

如果它只是一个在其他地方定义的函数,你可以修改我用钩子嘲讽给出的例子:

import { someFunction } from '../path/to/util';
jest.mock('../path/to/util', () => ({
someFunction: jest.fn(),
}));
describe('Button click', () => {
it('button click', async () => {
render(<SomeComponent />);
const button = await screen.findByTestId('button');
fireEvent.click(button);
// if there are some precise arguments given to `someFunction` maybe 
// use `toHaveBeenCalledWith` instead
expect(someFunction).toHaveBeenCalled();
});
});

someFunction()需要对您的应用程序产生一些副作用。你可以测试这些副作用。例如,如果someFunction()递增计数状态值,您可以在组件,以检查单击按钮时计数是否增加。

最新更新