【发布时间】:2019-04-16 15:55:07
【问题描述】:
长话短说,我有一个导入 vanilla.js 组件的 React 应用程序。该组件与 React 应用程序之外的 DOM 交互,但有时 React 应用程序需要使用该组件。当我尝试浅渲染导入 Login 组件的 React 组件时,Jest 挂断了 vanilla.js 登录组件中的“addEventListener”:
TypeError: Cannot read property 'addEventListener' of null
90 | }
91 |
> 92 | document.querySelector(config.selectors.loginModal).addEventListener('click', (e) => closeLogin(e));
| ^
93 | document.querySelector(config.selectors.loginClose).addEventListener('click', (e) => closeLogin(e));
94 | };
所以我有我的反应应用程序:
import React from 'react';
import Login from '../login';
const Component = () => {
return (
<h3>
<span className='cc-stats-login-btn' onClick={(e) =>
Login.openRegister(e, 'Statistics')}>Register</span>
or
<span className='cc-stats-login-btn' onClick={(e) => Login.openLogin(e, 'Statistics')}>login</span>
to view advanced analytics and graphs
</h3>
);
};
该应用的测试目前如下所示:
document.body.innerHTML =
'<div class="login-modal-bg">' +
' <div class="login-modal-close"></div>' +
'</div>';
describe('<Component />', () => {
test('renders', () => {
const wrapper = shallow(
<Component />
);
expect(wrapper.exists()).toBe(true);
});
});
Jest 似乎失败的登录组件的 js:
const Login = (() => {
const config = {
selectors: {
loginModal: '.login-modal-bg',
loginClose: '.login-modal-close'
}
};
[...]
const initialize = () => {
document.querySelector(config.selectors.loginModal).addEventListener('click', (e) => closeLogin(e));
document.querySelector(config.selectors.loginClose).addEventListener('click', (e) => closeLogin(e));
};
};
据我所知,根据 Jest 文档,我只需要一个简单的字符串作为“模拟 dom”,并且 addEventListener 应该可以工作。但我得到的只是上面的 TypeError。有什么想法吗?
【问题讨论】:
-
可测试性是直接 DOM 访问在 React 中不是一个好主意的原因之一。我建议模拟
document.querySelector调用而不是模拟 DOM。 -
我同意直接 DOM 访问在 React 中不是很好。但由于与业务相关的决策非常陌生,这不是我能做的。我尝试了以下方法来模拟 document.querySelector,但都不起作用:
document.querySelector = jest.fn();global.document.querySelector = jest.fn();global.document.querySelector.addEventListener = jest.fn(); -
结果如何?
-
总是同样的错误:
TypeError: Cannot read property 'addEventListener' of null -
是的,这是一种反模式。我更新了答案。由于 addEventListener 甚至没有在被测试的组件中使用,所以甚至不需要打扰它。模拟整个登录模块并单独测试。
标签: javascript reactjs jestjs enzyme