I'd like to have my image filenames / paths when using Jest Snapshots

javascript, jestjs, reactjs, unit-testing

Solution

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"
    }
  }
}

Problem

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!

Original source