reactjs - Testing React component that relies on externally imported js with Enzyme
问题描述
I've got a bit of an annoying issue here while trying to test a react modal class component in Enzyme, the class uses bootstrap and jQuery, application below.
componentDidMount() {
// @ts-ignore
$('#' + this.props.modalId).modal('toggle');
this.addKeydownHandler();
}
componentWillUnmount() {
this.removeKeydownHandler();
// @ts-ignore
$('#' + this.props.modalId).modal('toggle');
}
addKeydownHandler = () => {
$(document).on('keydown', (e: any) => { this.preventTabKey(e) });
}
removeKeydownHandler = () => {
$(document).off('keydown', (e: any) => { this.preventTabKey(e) });
}
I'm importing everything needed in my index file so they are accessible across the whole website as below.
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap/dist/css/bootstrap-theme.css';
import * as jquery from 'jquery';
(window as any).jQuery = jquery;
import 'popper.js';
import '../node_modules/bootstrap/dist/js/bootstrap.min.js';
And I'm calling Enzyme's mount as below.
var children = <div className="fgsr" ><p>Test</p></div>
var modal = Enzyme.mount(
<Modal modalId={"testId"} >
{children}
</Modal>
);
The problem is when I just mount the Modal for testing I get various errors - "TypeError: $(...).modal is not a function" and "Bootstrap js needs jQuery", if I just add the bootstrap js
The immediate/hacky fix is to simply add the imports below to the Modal class, but obviously don't want to include multiples of large files just to get tests to run.
import * as jquery from 'jquery';
(window as any).jQuery = jquery;
import '../../../../node_modules/bootstrap/dist/js/bootstrap.min.js';
Is there a workaround for this or a way to add extra imports to an Enzyme mounted wrapper?
解决方案
There doesn't seem to be any way of injecting externally imported js files into an enzyme wrapper for testing but there's a good workaround. I simply created a utility test component with all the dependencies imported that took children as props and simply returned the children in that component as below.
import * as React from 'react';
import * as jquery from 'jquery';
(window as any).jQuery = jquery;
import 'popper.js';
import '../../../node_modules/bootstrap/dist/js/bootstrap.min.js';
export interface Props {
children: JSX.Element;
}
const DependencyContainer = ({ children }: Props) => {
return (children);
}
export default DependencyContainer;
And then in my test class just wrapped my component in that container.
var modal = Enzyme.mount(
<DependencyContainer>
<Modal>
{children}
</Modal>
</DependencyContainer>
);
This way no additionally files need to be imported into production code.
推荐阅读
- android - 如何发送带有数据和列表的 POST 请求
在改造中遵循android中的MVP模式 - postgresql - 使用 PostgreSQL 的 AspNetCore.Identity:如何创建结构?
- node.js - 如何在使用 NodeJS、Express 和 mongodb 更新旧表单数据之前检索旧表单数据!Ejs是模板吗?
- javascript - 如何用 ReactJS 中的变量替换查询中的参数中的字符串
- excel - Excel:返回/自动换行/firstpage.footer中的第二行或更多行?
- ios - 选择退出 SceneDelegate 后 Xcode 未调用应用程序委托
- java - jaxrs 应用程序中的公共资源不起作用
- python - Python - Pandas - 合并两个具有不同时间戳频率的 DataFrame
- regex - 将非捕获组添加到字符类
- c# - UTF-8 字符转换为 c# webserver