Jest Snapshots for Storybook

Eric Clemmons
Dec 5, 2016 · 2 min read
Storybook “stories” convert React components into a testable playground.

Storybook is an extremely powerful & productive way to build React components. They’re effectively tests, so it makes sense to version them along with the rest of your test-suite.

Storyshots are Kadira’s answer to this, but don’t use Jest under the hood, so you miss out on Jest’s mocking capabilities.

Luckily, it’s fairly trivial for Jest to snapshot stories itself.

How To Snapshot Stories

1. Install Jest.

yarn add --dev jest
# or
npm install --save-dev jest

2. Add React support to Jest.

yarn add --dev babel-jest react-test-renderer
# or
npm install --save-dev babel-jest react-test-renderer

3. Modify your `package.json` to run `jest`:

{
"test": "jest --config .jestrc"
}

Note: .jestrc may be implicitly used in the future.

4. Mock out non-JS files (e.g. `.css`) & `@kadira/storybook` in `.jestrc`:

{
"moduleNameMapper": {
"\\.(css)$": "<rootDir>/__mocks__/.$1.js",
"^@kadira/storybook$":
"<rootDir>/__mocks__/@kadira/storybook"
}
}

Libraries like react-codemirror require importing CSS files, which will throw exceptions within Jest.

If you’re using CSS Modules, consider identity-obj-proxy, which will let you easily reference properties (e.g. styles.foo).

Note: Until facebook/jest#1774 & facebook/jest#462 are resolved, namespaced mock packages must be explicitly listed.

5. Create __mocks/.css.js:

module.exports = __filename.replace(process.cwd(), “~”);

CSS files are replaced with their relative path, so tests don’t break in CI.

6. Create __mocks__/@kadira/storybook.js:

import renderer from “react-test-renderer”;// Mocked version of `import { action } from “@kadira/storybook”`.
export const action = (actionName) => jest.fn();
// Mocked version of:
// import { storiesOf } from “@kadira/storybook
export const storiesOf = (groupName) => {
// Mocked API to generate tests from & snapshot stories.
const api = {
add(storyName, story) {
describe(groupName, () => {
it(storyName, () => {
const component = renderer.create(story());
expect(component.toJSON()).toMatchSnapshot();
});
});
return api;
},
// Any `storybook-addon-*` packages may require noop-ing them:
addDecorator() {
return api;
},
};
return api;
};

Note: Once facebook/jest#2094 is released, you can customize snapshot names!

7. Move *.stories.js under __tests__.

Jest will automatically discover & run any .js under __tests__.

8. Run Tests.

Stories & Unit tests both have snapshots.

Eric Clemmons

Written by

I write about tech (JavaScript, node, GraphQL, React, webpack) and Leadership. Currently building GraphQL apps @Starbucks.