I've started using Jest a lot in a new project, and I am now using the Snapshot functionality of Jest.
In a nutshell, what it does is render your components in a string, store that on disk (as a snapshot, that you can check-in in your repo), and when you run your tests later on it will compare that the snapshot didn't change.
My issue is to do with importing images:
The usual way to deal with that with Jest is to specify a handler for importing those, to mock them and return a random string.
That way, your tests won't have to actually load the image, it will just be mocked (otherwise you'll get exceptions, as Node doesn't know how to handle import img from './image.png
, only Webpack does via a loader).
In the Jest configuration, you would do something like that:
"jest": {
"moduleNameMapper": {
"^.+\\.(png|jpg|jpeg|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/app/__mocks__/fileMock.js",
"^.+\\.(css|less|scss)$": "identity-obj-proxy"
},
[...]
}
As you can see, images (png, jpeg, etc.) are all "resolved" using fileMock, which is simply this:
module.exports = 'test-file-stub';
My issue here is that the mocking goes a bit too far: it always return the same string, which means my snapshots for a component that renders flag look like:
exports[`components - Flag should match the snapshot 1`] = `
<img
alt="Flag"
className="image"
src="test-file-stub" />
`;
(the input was something like <Flag country="fr" />
)
What I would like is my snapshot to be rendered as such:
exports[`components - Flag should match the snapshot 1`] = `
<img
alt="Flag"
className="image"
src="/some/path/fr.png" />
`;
I don't believe I'm the only one facing this issue, but on the other hand I couldn't find any resource anywhere solving this.
Thanks!
Using Jest snapshots will help you ensure that your UI changes are deterministic and that you are aware when changes are made. Using that information, you can determine whether the changes were intended or not. You will be using the snapshots you create with Jest to simulate changes in a React application.
What are Snapshots: A snapshot is nothing but a configuration file defining your component style, UI, and props. The test case will look something like this: __tests__/someComponent.component.test.js. import React from 'react'; import renderer from 'react-test-renderer'; import SomeComponent from '../SomeComponent.
When writing snapshot tests for a React component, you first need to have code in a working state. Then, generate a snapshot of its expected output given certain data. The snapshot tests are committed alongside the component. Jest, a testing framework, will compare the snapshot to the rendered output for the test.
In snapshot testing, the output of a function is saved in a file (the “snapshot”), and when the test runs, it compares this saved output with the output of the function when it is run each time in the test suite.
Instead of relying on moduleNameMapper
you can specify a custom transform
where you return the image path instead of its source. A working example can be found under Mocking CSS Modules, pasting it below to make things easier.
// fileTransformer.js
const path = require('path');
module.exports = {
process(src, filename, config, options) {
return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';';
},
};
and
// package.json (for custom transformers and CSS Modules)
{
"jest": {
"moduleNameMapper": {
"\\.(css|less)$": "identity-obj-proxy"
},
"transform": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/fileTransformer.js"
}
}
}
Those having issues with Valentin
's suggestion and shallow rendering can try including this line within transform:
\\.(js|jsx)$": "babel-jest"
so that it becomes:
// package.json
{
"jest": {
"moduleNameMapper": {
"\\.(css|less)$": "identity-obj-proxy"
},
"transform": {
"\\.(js|jsx)$": "babel-jest",
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/fileTransformer.js"
}
}
}
The file fileTransformer.js
remains the same!
Note: Couldn't comment on his answer as I lack the 50 reputation to comment; this is my first answer here!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With