Jest Snapshots for Storybook

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](http://twitter.com/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](http://twitter.com/kadira/storybook)”`.
export const action = (actionName) => jest.fn();

// Mocked version of:
// import { storiesOf } from “[@kadira/storybook](http://twitter.com/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.

All done!

For better syntax-highlighting & a running example, check out the source repo:

ericclemmons/jest-storybook

summary: How to take Jest snapshots from Storybook (before Storyshots existed) tags: [jest, testing, javascript, storybook]

If you’d like to stay informed of other developer-centric tools & projects, follow me on Twitter:

Eric Clemmons (@ericclemmons) | Twitter

The latest Tweets from Eric Clemmons (@ericclemmons). Creator of React Resolver, Genesis/Evolution for WordPress. Purveyor of a better Developer Experience. VP of Software Development @HigherEdHQ. iPhone: 30.266818,-97.737081

👋