测试库 React 在异步后不会触发点击

ale*_*308 6 async-await reactjs jestjs react-testing-library

我正在尝试用 Jest 编写一个测试。当fireEvent.clickasync 之后出现时,it它不会触发该功能。

这正是描述问题的几行代码胜过数百个单词的确切情况。在下面的代码片段中,除了测试本身的名称之外,第二个和第三个测试完全相同(复制和粘贴)。

import {render, screen, waitFor, fireEvent} from '@testing-library/react';
import React from 'react';

const Component = ({asyncClick, syncClick}) => {
    function onClick(){
        console.log('clicked');
        syncClick();
        setTimeout(() => {
            asyncClick();
        }, 50);
    }
    return <div data-testid="toBeClick" onClick={onClick}>

    </div>;
}

describe('a test', function(){
    it('element exists', function(){
        render(<Component/>);
        let el = screen.getByTestId('toBeClick');
        expect(el).toBeInTheDocument();
    });

    it('element Click', async function(){
        let syncClick = jest.fn();
        let asyncClick = jest.fn();
        render(<Component asyncClick={asyncClick} syncClick={syncClick} />);
        let el = screen.getByTestId('toBeClick');
        fireEvent.click(el);
        expect(syncClick).toHaveBeenCalledTimes(1);
        await waitFor(() => {
            expect(asyncClick).toHaveBeenCalledTimes(1);
        });

    });

    it('element Click / 2', async function(){
        let syncClick = jest.fn();
        let asyncClick = jest.fn();
        render(<Component asyncClick={asyncClick} syncClick={syncClick} />);
        let el = screen.getByTestId('toBeClick');
        fireEvent.click(el);
        expect(syncClick).toHaveBeenCalledTimes(1);
        await waitFor(() => {
            expect(asyncClick).toHaveBeenCalledTimes(1);
        });

    });

})
Run Code Online (Sandbox Code Playgroud)

第二次测试通过。第三次测试失败。为什么?

作为旁注,从第二个测试中删除async/awaitwaitFor,甚至第三个测试也开始通过。

-- UPDATE 看起来失败是由于 jest-setup.js 中的导入:

require('ionic/js/ionic.js');
Run Code Online (Sandbox Code Playgroud)

我正在导入 Ionic v1,它破坏了测试。

Ale*_*aev 1

包装在act中触发某些内容的异步操作。

act(() => {
  fireEvent.click()
});
Run Code Online (Sandbox Code Playgroud)

可以尝试使用jest.useFakeTimers() 和 jest.runAllTimers()

在测试开始jest.useFakeTimers()并单击后调度 jest.runAllTimers()

如果没有效果可以尝试

await new Promise(resolve => setTimeout(resolve, 0));
Run Code Online (Sandbox Code Playgroud)