Using Jest Mocks to Prevent Non-Deterministic or Otherwise Changing Components from Continously Resulting in Snapshot Diffs

Nick Scialli
August 30, 2020

New — Check out my free newsletter on how the web works!

failing tests

Snapshot testing is great. I work with React a lot and frequently use Storybook to do visual and snapshot testing of my components. It can help quickly identify any regressions and undesired behavior by pointing out when your components render differently than they did the last time you ran your test suite.

The Problem of Non-Deterministic or Otherwise-Changing Components

Snapshot diffs can sometimes be meaningless. For example, if you snapshot test a component that contains a random number generator, you’ll constantly get snapshot diffs when nothing has really changed. These diffs are essentially a nuisance—we don’t want to keep having to approve them over and over.

A Concrete Example: The Current Timestamp

Let’s say our app has a section that tells users the current time. My app will be an extreme example and will tell the time down to the second. Note that this is a functional React component with hooks. If you don’t understand the code, no worries, I’ll show you what gets rendered in the browser in a moment.


import React, { useState, useEffect } from 'react';

const getCurrentTimestamp = () => new Date().toLocaleTimeString();

export const Timer = () => {
  const [time, setTime] = useState(getCurrentTimestamp());
  useEffect(() => {
    let refresh = setInterval(() => {
    }, 1000);
    return () => {
  }, []);

  return <div>The time is {time}</div>;

If I fire up my app and load it in the browser, I see a very simple dynamic clock.

simple clock in browser

Snapshot Testing our Clock

Here’s a really simply Storybook test for my Timer component.

import React from 'react';
import { Timer } from '../timer';

export default {
  title: 'Components/Timer',
  component: Timer,

export const Default = () => <Timer />;

However, whenever I run snapshot testing for this component, it fails!

failed test

The time changes every time I take a snapshot of the component, so of course the snapshot will fail: we get something different rendering every time.

Fixing the Issue: Mocking Out Our Dynamic Component

Fortunately, there’s a pretty simple fix for our issue! In this instance, our Storybook-related snapshots are driven by a config file, storybook.test.jsx. Prior to any modification, this config file looks like this:

import initStoryshots from '@storybook/addon-storyshots';

We can modify this file by mocking the import of Timer from the timer.jsx file! That way, any use of the component in our snapshot tests will use the mock we provide here rather than the actual component.

import React from 'react';
import initStoryshots from '@storybook/addon-storyshots';

jest.mock('../timer.tsx', () => ({
  Timer: () => <timer />,


Here we’ve basically told jest that, instead of rendering our dynamic component for snapshot tests, just go ahead and render <timer />. That way, we won’t be bothered by dynamic snapshots but we’ll also be assured that the timer is rendering when it should.

We can now run our snapshot tests and will no longer be annoyed by these frequently-changing components!

🎓 Learn how the web works

One of the best ways to level up your tech career is to have a great foundational understanding of how the web works. In my free newsletter, How the Web Works, I provide simple, bite-sized explanations for various web topics that can help you boost your knowledge. Join 2,500+ other learners on the newsletter today!

Signing up is free, I never spam, and you can unsubscribe any time. You won't regret it!

Sign up for the newsletter »
Nick Scialli

Nick Scialli is a senior UI engineer at Microsoft.

© 2024 Nick Scialli