jest 单元测试生成测试覆盖率时 antd 组件未定义错误

问题

使用 jest 进行单元测试时,对引用了 antd 的组件进行单元测试时可以成功通过测试。但是当使用 --coverage 参数生成测试覆盖率报告时,出现了报错。

测试的 UI 组件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import React from 'react';
import { Card } from 'antd';

const { Meta } = Card;

class User extends React.Component {
render() {
return (
<Card>
<Meta />
</Card>
);
}
}

报错信息如下:

1
2
3
4
FAIL  src/routes/User/__test__/User.test.js
● Test suite failed to run

ReferenceError: Card is not defined

解决

方法 1

不使用 ES6 解构赋值方法引用 Card 内置组件

1
2
// const { Meta } = Card;
const Meta = Card.Meta;

方法 2

直接使用 Card 内置组件

1
2
3
4
5
6
7
render() {
return (
<Card>
<Card.Meta />
</Card>
);
}

方法3

本问题出现的原因关键在于使用了 babel-plugin-import 插件,我们可以通过 babelenv 配置项来决定何时启用 babel-plugin-import 插件。需要知道的是进行 jest 测试时默认会将 NODE_ENV 设置为 testbabelenv 选项的值将从 process.env.BABEL_ENV 获取,如果没有的话,则获取 process.env.NODE_ENV 的值,它也无法获取时会设置为 development。在平时开发以及打包时 NODE_ENV 一般约定值为 developmentproduction,我们可以在这两个环境时才启用 babel-plugin-import 插件。不过由于取消了按需加载 antd 样式,在测试时可能有性能的影响。

另外在 jest 测试时需要将 babel-preset-env 中的 modules 选项打开 (babel 7 同)。

这里使用 js 文件来复用相同的配置。babel 配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// .babelrc.js
const pluginImportConfig = [
'import',
{ libraryName: 'antd', libraryDirectory: 'es', style: 'css' },
];

module.exports = {
presets: [['env', { modules: false }], 'react', 'stage-2'],
env: {
// 在 test 环境启用 env 的 modules 配置项
test: {
presets: ['env', 'react', 'stage-2'],
},
development: {
plugins: [pluginImportConfig],
},
production: {
plugins: [pluginImportConfig],
},
},
};

参考资料: