React Shallow Snapshot
Tags: react, testing, snapshots, mocking
Published: 2019-05-16 04:48:02

---
title: React Shallow Snapshot
published: true
description: Snapshot testing could be a joke, but would be a joy!
tags: react, testing, snapshots, mocking
---
As one my friend once said - __In every joke there is a joke__. The _inner joke_.

This is quite deep philosophical observation which means basically - you might derive one joke from another, making the first one even more funny. You may find endless _reflections_ and nuances, making a little joke a real THING.

And here is the joke of mine:

{% twitter 1109261285881835521 %}

Does not sounds funny? So let's find a real joke inside the joke, and just do that it said - let's create a shallow snapshot! :)

```js
import React from 'react';
import Link from 'react-router';
import Section from './section';

// const Section = ({children}) => <section><SomeStuff/>{children}</section>

describe('Mark-testing', () => {
  it('should match snapshot', () => {
    expect(shallow(<Section><Link>click me</Link></Section>)).toMatchSnapshot());    
  });
});
```

What we just did? We tested a `skeleton`, and, long story _shot_, the result would be....

```js
<section>
  <SomeStuff />
  <Link to=\\"#\\">
    click me
  </Link>
</section>
```

> We tested nothing.

That was something _expected_. This is how shallow rendering works, and that's a feature, not a bug. A reason [Why I Always Use Shallow Rendering](https://hackernoon.com/why-i-always-use-shallow-rendering-a3a50da60942).

But... you are right - that's absolutely useless 😢

{% twitter 1109601176268369920 %}

So - `shallow` would not help is find the inner joke. Let's `mount` then!

```js
describe('Mark-mount-testing', () => {
  it('should match snapshot', () => {
    expect(mount(<Section><Link>click me</Link></Section>)).toMatchSnapshot());    
  });
});
```

What would happen next? 😉 `Error: Uncaught [Error: Invariant failed: You should not use <Link> outside a <Router>]`

So let's wrap everything a router and rerun. Now our snapshot is:
```js
<StaticRouter>
  <Router history={{...}} staticContext={{...}}>
    <Section>
      <section>
        <SomeStuff>
          <div>
            Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry&#39;s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.
          </div>
        </SomeStuff>
        <Link to=\\"#\\">
          <a onClick={[Function: onClick]} href=\\"/\\">
            click me
          </a>
        </Link>
      </section>
    </Section>
  </Router>
</StaticRouter>
```

You know - that's __much better__ than before but at the same time __a bit more__ than I expected.

In my personal experience, with StyledComponets, MoreComponents and MoreDeeperComponents snapshots could be HUGE and provide nothing more, but noise. Uter crap!


# Could we find something in between?

[React Testing Recipes](https://reactjs.org/docs/testing-recipes.html) has a few hints about making snapshots testing better:

> It’s typically better to make more specific assertions than to use snapshots. These kinds of tests include implementation details so they break easily, and teams can get desensitized to snapshot breakages. __Selectively mocking some child components__ can help reduce the size of snapshots and keep them readable for the code review.

> By `mocking` they assumed `jest.mock`, but I've got another solution for you - mocking __components__, not __modules__.



Yes, piece a cake. Let's use a __finite component__ idea, I've explained in depth here:

{% link  https://dev.to/thekashey/infinite-war-995 %}


```js
import React from 'react';
import Link from 'react-router';
import { createElement, remock } from 'react-remock';
import Section from './section';

describe('Mark-finite-mount-testing', () => {
  it('should match snapshot', () => {
    remock.push();

    // replace Link by another component
    remock.mock(Link, (_, props) => createElement('router-link', props));

    expect(shallow(<Section><Link>click me</Link></Section>)).toMatchSnapshot());   
    remock.pop(); 
  });
});
```

Here we just __mocked__ a `Link` component, removing the dependency to `Router` and kept the rest unchanged. Updated snapshot is:

```js
<Section>
  <section>
    <SomeStuff>
      <div>
        Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry&#39;s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.
      </div>
    </SomeStuff>
    <router-link to="#">
      click me
    </router-link>
  </section>
</Section>
```

Clean and Sound. Just without some branches we __cuted off__, making your snapshot more shallow, but not as shallow, as using the real `shallow` 🤯

You might mock anything providing a `variable`, like I did, or `name`, or `regexp`. Cut, or replace (we kept children of a `Link`), as much as needed.

A good example is a __FancyButton__, which actually is a combination of 2 `<ThemeProviders>`, a few `<StyledComponents>`, and a few more `HOCs`. 

This is a __ONE Component__ for you

![Oh CRAP](https://thepracticaldev.s3.amazonaws.com/i/48r1bz6j450d10kekf4l.png)

With remock you might make it a __ONE component__ for your snapshot.

#### PS
Examples were provided are in the Jest syntax, while snapshots were generated using `mocha` + `chai-jest-snapshot`

```js
const wrapper = mount(<Section><Link to="#">click me</Link></Section>);
expect(wrapper.debug()).to.matchSnapshot();
// ^ yes, wrapper.debug() ^ produces the best code, 
// while `.html()` or `.render` or hides some details(props) 
// you might wanna use, or generates a single line of code, 
// you will not able to review/merge.
```

> So, you will not believe, but finite component and [react-remock](https://github.com/theKashey/react-remock) could make _shallow snapshots_ a thing. If you use a `mount`... That was the joke :)

{% twitter 1118633897460240385 %}

Mark authors best memes. I liked this one.

> PS: And the other one - there is also [the same joke about dependency mocking](https://twitter.com/markdalgleish/status/1126651341130981377), and you know... for the things like [stricter](https://github.com/stricter/stricter) it's a fun!