代码之家  ›  专栏  ›  技术社区  ›  TMH

如何用act正确测试React

  •  1
  • TMH  · 技术社区  · 3 年前

    我正试着测试一个组件,但它出错了

    console.error
        Warning: An update to Example inside a test was not wrapped in act(...).
        
        When testing, code that causes React state updates should be wrapped into act(...):
        
        act(() => {
          /* fire events that update state */
        });
        /* assert on the output */
        
        This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
            at Example (/Users/thr15/Developmemt/Boost/basket-creator/frontend/src/Page/F1/Example.tsx:5:29)
            at WrapperComponent (/Users/thr15/Developmemt/Boost/basket-creator/frontend/node_modules/enzyme-adapter-utils/src/createMountWrapper.jsx:49:26)
    
    

    下面是我的组件的简化版本

    import {useState} from 'react';
    
    function Example(): JSX.Element {
    
        const [name, setName] = useState('');
        const [, setLoading] = useState(false);
        const [results, setResults] = useState<number[]>([]);
    
        /**
         * Search the baskets.
         */
        const search = async () => {
    
            // Let the UI know we're loading
            setLoading(true);
    
            // Get the baskets
            try {
                const baskets: number[] = await (await fetch('/test?name=' + name)).json();
    
                // Give the UI the data
                setLoading(false);
                setResults(baskets);
            } catch (e) {
                console.error(e);
            }
        };
    
        return <div className={"content"}>
            <input value={name} onChange={(e) => setName(e.target.value)}/>
            <button onClick={search}>Search</button>
            {results.length}
        </div>
    }
    
    export default Example;
    

    到目前为止我的测试

    import Enzyme, {mount} from 'enzyme';
    import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
    import Example from "./Example";
    
    Enzyme.configure({adapter: new Adapter()});
    
    describe('Example', () => {
        test('searching requests the correct URL', () => {
    
            fetch = jest.fn(() =>
                Promise.resolve({
                    json: () => Promise.resolve([{a: 1}, {b: 2}]),
                })
            );
    
            let searchButton;
            const wrapper = mount(<Example/>);
            const input = wrapper.find('input').at(0);
            searchButton = wrapper.find('button').at(0);
    
            input.simulate('change', {target: {value: 'Driver Name'}});
            searchButton.simulate('click');
            
            expect(searchButton.text()).toBe('Search');
            expect(fetch.mock.calls.length).toBe(1);
            expect(fetch.mock.calls[0][0]).toBe('/test?name=Driver Name');
        });
    });
    

    任何人(可能还有我!)未来

    describe('Example', () => {
        test('searching requests the correct URL', async () => {
    
            fetch = jest.fn(() =>
                Promise.resolve({
                    json: () => Promise.resolve([{a: 1}, {b: 2}]),
                })
            );
    
            let searchButton: ReactWrapper;
            const wrapper = mount(<Example/>);
            const input = wrapper.find('input').at(0);
            searchButton = wrapper.find('button').at(0);
    
            input.simulate('change', {target: {value: 'Driver Name'}});
    
            await act(async () => {
                searchButton.simulate('click');
            });
    
            expect(searchButton.text()).toBe('Search');
            expect(fetch.mock.calls.length).toBe(1);
            expect(fetch.mock.calls[0][0]).toBe('/test?name=Driver Name');
        });
    });
    
    1 回复  |  直到 3 年前
        1
  •  1
  •   JAM    3 年前

    我猜是点击搜索按钮产生了act警告。

    react@16.9.0 , act 已更改为返回承诺,这意味着您可以在测试异步处理程序时避免这些类型的警告。

    await act(() => {
      searchButton.simulate('click');
    })        
    

    以下是有关该主题的更多资源,可能会对您有所帮助: