在添加 eventListeners 时测试 React useEffect 钩子



我的 React 代码中有一个功能组件,如下所示:

const Compo = ({funcA}) => {
useEffect(() => {
window.addEventListener('x', funcB, false);
return () => {
window.removeEventListener('x', funcB, false); 
}
});
const funcB = () => {funcA()};      
return (
<button
onClick={() => funcA()}
/>
);
};
Compo.propTypes = {
funcA: func.isRequired
}
export default Compo;

我需要测试上面的功能组件,以确保按照 useEffect(( 钩子中提到的添加和删除事件侦听器。

这是我的测试文件的样子 -

const addEventSpy = jest.spyOn(window, 'addEventListener');
const removeEventSpy = jest.spyOn(window, 'removeEventListener');
let props = mockProps = {funcA: jest.fn()};
const wrapper = mount(<Compo {...props} />);
const callBack = wrapper.instance().funcB;     <===== ERROR ON THIS LINE
expect(addEventSpy).toHaveBeenCalledWith('x', callBack, false);
wrapper.unmount();
expect(removeEventSpy).toHaveBeenCalledWith('x', callBack, false);

但是,我在声明"callBack"常量的行上收到以下错误(在代码中突出显示(:

类型错误: 无法读取空的属性"funcB">

实际上,它使组件呈现正常,但 wrapper.instance(( 的计算结果为 null,这引发了上述错误。

有人可以知道我缺少什么来修复上述错误吗?

这是我的单元测试策略:

index.tsx

import React, { useEffect } from 'react';
const Compo = ({ funcA }) => {
useEffect(() => {
window.addEventListener('x', funcB, false);
return () => {
window.removeEventListener('x', funcB, false);
};
}, []);
const funcB = () => {
funcA();
};
return <button onClick={funcB} />;
};
export default Compo;

index.spec.tsx

import React from 'react';
import { mount } from 'enzyme';
import Compo from './';
describe('Compo', () => {
afterEach(() => {
jest.restoreAllMocks();
});
it('should call funcA', () => {
const events = {};
jest.spyOn(window, 'addEventListener').mockImplementation((event, handle, options?) => {
events[event] = handle;
});
jest.spyOn(window, 'removeEventListener').mockImplementation((event, handle, options?) => {
events[event] = undefined;
});
const mProps = { funcA: jest.fn() };
const wrapper = mount(<Compo {...mProps}></Compo>);
expect(wrapper.find('button')).toBeDefined();
events['x']();
expect(window.addEventListener).toBeCalledWith('x', expect.any(Function), false);
expect(mProps.funcA).toBeCalledTimes(1);
wrapper.unmount();
expect(window.removeEventListener).toBeCalledWith('x', expect.any(Function), false);
});
});

100% 覆盖率的单元测试结果:

PASS  src/stackoverflow/57797518/index.spec.tsx (8.125s)
Compo
✓ should call funcA (51ms)
-----------|----------|----------|----------|----------|-------------------|
File       |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files  |      100 |      100 |      100 |      100 |                   |
index.tsx |      100 |      100 |      100 |      100 |                   |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        9.556s

源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/57797518

相关内容

  • 没有找到相关文章

最新更新