javascript - 在 componentDidMount() 中设置时如何模拟 eventListener
问题描述
那是我的组件
class Foo extends React.Component {
constructor(props) {
super(props);
this.state = {
...
};
this.input = React.createRef();
}
componentDidMount() {
const id = 'bar';
let element = document.getElementById(id);
element.addEventListener('transitionend', () => {
this.setState({ ... });
}, false);
}
...
当我这样设置测试时
import React from 'react';
import { mount } from 'enzyme';
import 'jsdom-global/register';
import Foo from './';
it('renders the component correctly', () => {
const component = mount(
<Foo />
);
component
.unmount();
});
我明白了
console.error node_modules/react-dom/cjs/react-dom.development.js:16647 组件出现上述错误:in Foo (created by WrapperComponent) in WrapperComponent
考虑向树中添加错误边界以自定义错误处理行为。● 正确渲染组件 TypeError: Cannot read property 'addEventListener' of null
我试过
ReactDOM.render(<Foo />, document.body);
或添加这个
const map = {};
Window.addEventListener = jest.genMockFn().mockImpl((event, cb) => {
map[event] = cb;
});
还有这个
const map = {};
document.addEventListener = jest.fn((event, cb) => {
map[event] = cb;
})
在测试中安装之前<Foo />
。但这一切都带来了同样的错误。这是为什么?
解决方案
在 React 中不鼓励直接访问 DOM 的原因之一是因为它使测试变得更加复杂和不可预测。
可以在安装组件之前完全模拟 DOM:
const elementMock = { addEventListener: jest.fn() };
jest.spyOn(document, 'getElementById').mockImplementation(() => elementMock);
可以测试被正确调用的存根:
expect(elementMock.addEventListener).toBeCalledWith('transitionend', expect.any(Function), false);
并且可以测试事件侦听器是否按预期更改状态:
const handler = elementMock.mock.calls[0][1];
handler();
...
推荐阅读
- reactjs - 相当于 Javascript 中的 base64 -d
- angular - 在 Azure DevOps 中使用 nx 影响 Nx Monorepro 的问题
- machine-learning - scikit-learn 的“虚拟分类器”能否应用于多类场景
- r - Filter_all(any_vars()) 我哪里出错了?
- internationalization - i18next-fs-backend 保存所有语言的缺失文件
- spark-streaming - Spark 流式传输:具有背压/控制功能的 Google Cloud Pub/Sub 的 DStream 连接器
- docker - 我无法从 Jenkins Docker Containers 卷曲到我的已部署应用程序
- extjs - EXTJS 7 areaChart 动态标记或标记自定义
- arm - 如何在 ARM 中找到十六进制数字的符号扩展?
- go - 如何检查值是否动态实现接口?