如何解决称为断言的函数如何断言
我有一个React组件来渲染输入。输入更改后,将调用通过props的更改处理程序的反跳版本。
我试图断言变更处理程序已被调用,但根据Jest的说法,不是。
WrappedInput
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
,并得到相同的错误。
解决方法
您将需要在测试时删除防抖动,或者使用假计时器,这样就无需等待实际的防抖动时间。 Jest自己的假计时器似乎不适用于Lodash的反跳动作。我发现@sinonjs/fake-timers
有用。您需要在测试之前安装假计时器,然后再将其卸载。这会将setTimeout
,Date
等替换为您控制的假货。
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')
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。