称为断言的函数如何断言

熊猫派对

我有一个React组件来渲染输入。更改输入时,将调用通过props的更改处理程序的反跳版本。

我试图断言变更处理程序已被调用,但根据Jest的说法,它不是。

包装输入

    import debounce from 'lodash.debounce';

    const WrappedInput = ({ data, onChange }) => {

        const [value, setValue] = useState(data.value);

        const handleSave = useCallback(
            value =>
                debounce(() => {
                    onChange({
                        value,
                    });
                }, 500),
            [onChange]
        );

        const handleChange = useCallback(
            event => {
                setValue(event.target.value);
                handleSave(event.target.value);
            },
            [saveChange]
        );

        return (
            <div data-testid="input-container">
                <Input
                    value={value}
                    onChange={handleChange}
                />
            </div>
        );
    };

WrappedInput.test

test('save occurs', async () => {
    const onChange = jest.fn(() => {});

    const { getByTestId } = renderWrappedInput({ data: {}, onChange });

    const input = await waitFor(() => getByTestId('input-container').querySelector('input'));
    fireEvent.change(input, { target: { value: 'asdf' } });

    expect(onChange).toBeCalledTimes(1);
});

我得到了错误Expected number of calls: 1 \n Received number of calls: 0我还尝试lodash.debouce通过jest.mock('lodash.debounce', () => () => onChange());onChange声明下面添加来模拟并得到相同的错误。

br

您需要在测试时删除反跳,或者使用假计时器,这样就不必等待实际的反跳时间。Jest自己的假计时器似乎不适用于Lodash的反跳动作。我发现这@sinonjs/fake-timers可行。您需要在测试之前安装假计时器,然后再将其卸载。这将取代setTimeoutDate等有假货,你控制。

import FakeTimers from '@sinonjs/fake-timers'

let clock
beforeEach(() => {
  clock = FakeTimers.install()
})
afterEach(() => {
  clock.uninstall()
})

test('save occurs', async () => {
    const onChange = jest.fn(() => {});

    const { getByTestId } = renderWrappedInput({ data: {}, onChange });

    const input = await waitFor(() => getByTestId('input-container').querySelector('input'));

    fireEvent.change(input, { target: { value: 'asdf' } });
    clock.tick(500) // advance the clock by the amount of the debounce

    expect(onChange).toBeCalledTimes(1);
});

如果您的React组件需要执行异步操作,即需要等待一个诺言解决,请使用await clock.tickAsync()代替clock.tick()假计时器的*** Async变体打破了事件循环,并让诺言得以执行。

附带说明一下,您可能想使用@testing-library/user-event而不是fireEvent-它公开了用于单击,键入,悬停等的更高级别的API。它可以更准确地模拟真实键入-例如,它首先单击控件,并且在两次击键之间具有可选的延迟。

import userEvent from '@testing-library/user-event'

// ..
// fireEvent.change(input, { target: { value: 'asdf' } });
// ↓
userEvent.type(input, 'asdf')

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章