酶无法浅表渲染,因为导入的脚本使用了'addEventListener'



长话短说,我有一个React应用程序正在导入vanilla.js组件。该组件在React应用程序之外与DOM交互,但有时React应用需要使用该组件。当我尝试浅层渲染导入Login组件的React组件时,Jest会挂断vanilla.js Login组件中的"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 |   };

所以我有了我的react应用程序:

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文档,我所需要的只是一个简单的字符串作为"mock dom",addEventListener应该可以工作。但我得到的只是上面的TypeError。有什么想法吗?

单元测试中针对DOM的测试(在Jest中不是真实的,因为它使用了JSDOM(提供了额外的移动部分。document.querySelector可以改为模拟:

const loginModalMock = jest.fn();
const loginCloseMock = jest.fn();
jest.spyOn(document, 'querySelector')
.mockReturnValue()
.mockReturnValueOnce({ addEventListener: loginModalMock })
.mockReturnValueOnce({ addEventListener: loginCloseMock })
const wrapper = shallow(
<Component />
);
...

在这种特定情况下,document.querySelector不用于测试模块。使用它的模块可以在测试文件的顶部进行模拟:

jest.mock('.../login', () => ({ openLogin: jest.fn() }));

最新更新