继上回讨论react-testing-library快速测试React组件渲染之后,你可能很快发现在实际使用当中遇到各种问题。比如这个:
因为在MyComponent.tsx
中,引入了CSS Module:
import * as React from "react";
import * as s from "./styles.scss";
export default function MyComponent() {
return <div className={s.container}>test</div>;
}
测试用例同一文中一样,并未做任何改动:
import * as React from "react";
import { render } from "@testing-library/react";
import MyComponent from "./MyComponent";
test("test render", () => {
const { getByText } = render(<MyComponent />);
expect(getByText("test")).toBeTruthy();
});
而且我的style.scss
真实存在着:
.container {
background: red;
}
那是怎么回事呢?
还记得你在打包工具如Webpack中配置的一系列loader吗?像:
import * as s from "./styles.scss";
这样的用法在JS文件中并不支持,能够这样使用是完全是因为loader在背后做了一系列工作,把这些语句“翻译”成了符合JS用法的语句。而测试框架并没有配置这样的loader,所以它在引入这段代码的时候会报错。
Jest支持一些类似loader的配置,让我们可以处理这样的情况。
用Jest transformer转换样式
Jest在错误提示中,提到了transform选项,它的默认值为;
{ "\\.[jt]sx?$": "babel-jest" }
transform
可以在识别到import匹配模式的文件时用一个转义器(transformer)处理该文件的内容。以上默认值就是在匹配到后缀名为.js
、 .jsx
、 .ts
、.tsx
的文件时用babel-jest
转义。
针对CSS Module的转义器可以在npm上找到,如:jest-transform-css。安装后在jest.config.js
添加以下配置来启用:
module.exports = {
transform: {
"\\.scss$": "jest-transform-css",
},
}
保存配置,再重新执行测试就可以通过啦!
写个简单Jest mock跳过样式
还有一种方法是在不干扰测试结果的情况下,干脆用Jest mock工具跳过这些测试。
首先我们需要准备一个mock代码文件如__mocks__/fileMock.js
:
module.exports = {};
然后告诉Jest遇到这些我需要识别的文件就直接找这个mock就好了。添加如下moduleNameMapper
选项到jest.config.js
:
module.exports = {
moduleNameMapper: {
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga|css|scss)$':
'<rootDir>/__mocks__/fileMock.js',
},
}
没错,这个方法还适用于其他任何不想识别的模块(不限于某种文件)。
保存配置,再重新执行测试就可以通过啦!
看看其他测试系列文:
- 前端写不写单元测试?| 创作者训练营
- React应用测试:配置Typescript, Jest, ESLint | 创作者训练营
- react-testing-library快速测试React组件渲染
- 用Jest mock隔离单元测试中的不可控因素
- 用react-testing-library快速测试React组件交互