如何让React Testing Library的各个测试用例互相独立无依赖
问题根源
你在describe块外层声明了全局的onCardClick mock 实例,所有测试用例共享同一个 mock 对象。afterEach(cleanup)只会清理渲染产生的DOM节点,不会重置Jest mock的调用记录,因此第一个用例的点击调用记录会被保留到第二个用例中,导致计数累加。
解决方案
以下两种方案都可以实现用例完全隔离:
- 方案1:每个测试用例单独声明mock函数
把mock函数的定义移动到每个test块内部,每个用例使用独立的mock实例,从根源避免数据污染。
示例代码:
afterEach(cleanup); describe('Card', () => { test('renders quote card and allows click', () => { const onCardClick = jest.fn(); const { getByTestId } = render(<Card onClick={onCardClick} />); fireEvent.click(getByTestId('card-root')); expect(onCardClick.mock.calls.length).toBe(1); }); test('renders card passes index on click', () => { const onCardClick = jest.fn(); const { getByTestId } = render( <Card onClick={onCardClick} index={2} /> ); fireEvent.click(getByTestId('card-root')); expect(onCardClick.mock.calls.length).toBe(1); expect(onCardClick.mock.calls[0][0]).toBe(2); }); });
- 方案2:全局声明mock,每次用例执行后清空调用记录
在afterEach钩子中加入重置mock的逻辑,清空所有mock的调用记录和实例:
示例代码:
const onCardClick = jest.fn(); afterEach(() => { cleanup(); jest.clearAllMocks(); // 清空所有mock的调用记录 // 如果只需要重置当前mock也可以写 onCardClick.mockClear() }); describe('Card', () => { test('renders quote card and allows click', () => { const { getByTestId } = render(<Card onClick={onCardClick} />); fireEvent.click(getByTestId('card-root')); expect(onCardClick.mock.calls.length).toBe(1); }); test('renders card passes index on click', () => { const { getByTestId } = render( <Card onClick={onCardClick} index={2} /> ); fireEvent.click(getByTestId('card-root')); expect(onCardClick.mock.calls.length).toBe(1); expect(onCardClick.mock.calls[0][0]).toBe(2); }); });
补充说明:如果需要同时重置mock的自定义实现,可以用
jest.resetAllMocks()替代jest.clearAllMocks()。
内容的提问来源于stack exchange,提问作者Piyush arora
相关产品推荐
相关产品推荐

