Following on from the react-testing-library discussion on how to quickly test react component renderings, you may soon find yourself running into problems in real life. Like this one:
Because in myComponent.tsx, CSS modules are introduced:
import * as React from "react";
import * as s from "./styles.scss";
export default function MyComponent() {
return <div className={s.container}>test</div>;
}
Copy the code
The test case is the same as in the article without any changes:
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();
});
Copy the code
And my style.scss is real:
.container {
background: red;
}
Copy the code
How did that happen?
Remember the series of loaders you configured in packaging tools such as Webpack? Like:
import * as s from "./styles.scss";
Copy the code
This usage is not supported in JS files and is only possible because loader does a lot of work behind the scenes to “translate” these statements into JS usage. The test framework does not configure such a loader, so it will report an error when importing this code.
Jest supports some Loader-like configurations that allow us to handle such situations.
Convert styles using Jest Transformer
Jest, in the error message, mentions the transform option, which defaults to;
{ "\\.[jt]sx? $": "babel-jest" }
Copy the code
Transform can process the contents of a file with an escape transformer when it recognizes a file that matches the import pattern. The above default value is escaped with babel-jest when matching files with the suffix.js,.jsx,.ts,.tsx.
An escape for CSS modules can be found on NPM, such as jest-transform-css. After installation add the following configuration to jest.config.js to enable it:
module.exports = {
transform: {
"\\.scss$": "jest-transform-css",}}Copy the code
Save the configuration and rerun the test to pass!
Write a simple Jest Mock to skip styles
Another option is to skip these tests with the Jest Mock tool without interfering with the test results.
First we need to prepare a mock code file such as __mocks__/ filemock.js:
module.exports = {};
Copy the code
Then tell Jest to look for the mock when I encounter the files I need to identify. Add the following moduleNameMapper option to 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',}}Copy the code
Yes, this method also works for any other module you don’t want to identify (not just a file).
Save the configuration and rerun the test to pass!
Check out the other test series:
- Does the front end write unit tests? | creators camp
- The React application test: configuration Typescript, Jest, ESLint | creator training camp
- React -testing-library quickly tests react component renderings
- Isolate uncontrollable factors in unit tests with Jest Mock
- Use react-testing-library to quickly test react component interactions