• Skip to main content
  • Skip to primary sidebar
  • Skip to footer

Alex Aitken

Technical and Engineering Leadership, Coaching, and Mentorship

Jest, React, and Mocking

February 12, 2018 By Alex Leave a Comment

Are you stuck with Proxyquire or Sinon?

Before we moved to Jest, we used Karma with Mocha/Chai. These come with no built-in mocking capabilities (as far as I’m aware). If you’re a C# developer, you know all about the different Mock frameworks (e.g. Moq), and you want to be able to do the same with your TypeScript, right? At least I do. I want to try my best to follow the SOLID principles (I’ll write about those later in the year).

So, because these testing frameworks come with no mocks, we had to use things like Sinon or Proxyquire. It’s doable. It really is. But why do you need these extra frameworks and all this extra code when there is already a test runner/framework that has it all built in. And… and it works perfectly with React because it’s built by the same guys (Facebook).

Enter Jest

Jest is an excellent testing framework with pretty good out of the box functionality. Firstly, it will parallelise your tests, so they’ll run faster. It only takes a couple of minutes to run hundreds/thousands of tests. I think when we implemented it, it was about half the time. It has excellent mocking built in. This is awesome for TypeScript because you can mock entire imports. There’s just one caveat; make sure the mock is before the component that imports the import you want to mock.

Enzyme

Before I continue about mocking (in tests), I should talk about Enzyme (from Airbnb). Enzyme is a godsend. It makes testing React code so much better. But, you have to be careful. We try to use shallow rendering rather than a full DOM render (mount). Why? Because it’s much faster as you don’t render everything. Also because you shouldn’t need to test child components within the parent component. I mean, you wouldn’t do that in C#, so why would you do that with Enzyme?

Below is an example of how you can test a component. Even without seeing the actual component’s code, you can get an idea of what the component looks like. It has a class named .my-class  and that has text inside of the props name. We can also see that it probably has a wrapper div with a class of .my-class-wrapper.

import * as React from 'react';
import { shallow } from 'enzyme';
import { MyComponent, MyComponentProps } from './MyComponent';

describe('<MyComponent />', () => {

    const initialProps: MyComponentProps = {
        name: 'John',
    };

    test('Should display name correctly', () => {
        const props  = {
            ...initialProps,
        };
        const myComponent = shallow(<MyComponent {...props} />);

        expect(myComponent).toMatchSnapshot();
        expect(myComponent.find('.my-class').at(0).text()).toBe(props.name);
        expect(myComponent.prop('className')).toBe('my-class-wrapper');
    });
});

Mocking

Sometimes you have complicated components with dependencies that you don’t want to worry about. Maybe, for example, you decide to use Google Maps, which has an external dependency in your SPA.  It does a network call and fails every time on your build server which doesn’t have internet access. You might have something else crazy. Who knows? Anyway, the point is that maybe you don’t want that loading during your tests. You can mock your API calls, or anything else.

import * as React from 'react';
import { shallow } from 'enzyme';
import { IMyApi } from './api';

const mockOnLoadFn = jest.fn();
const MyApi = jest.fn<IMyApi>((): IMyApi => ({
    getMyName: mockOnLoadFn,
}));

jest.mock('./api', () => ({
    MyApi,
}));

import { MyComponent, MyComponentProps } from './MyComponent';


describe('<MyComponent />', () => {

    const initialProps: MyComponentProps = {
        name: 'John',
    };

    test('Should display name correctly', () => {
        const props  = {
            ...initialProps,
        };
        const myComponent = shallow(<MyComponent {...props} />);
        myComponent.instance().componentDidMount();

        expect(mockOnLoadFn).toHaveBeenCalledTimes(1);
    });
});

You can tell from my test above, that probably during componentDidMount,  getMyName on the IMyApi is called once. This won’t call out to the actual API. It’s nicely mocked and can easily be tested. I know that calling into the instance of the component is not the best thing, but if you don’t want to mount a component, this is the better way to do it.

You can even return a value from the mock. It’s probably better to look at the Jest documentation rather than me trying to blabber about this. UNLESS… unless I get some more requests about mocking in tests etc.

Summary

Use Jest to test your React code. Use Enzyme in conjunction with React. Mocking/Stubbing is good where possible.

Reposted on Medium.

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook

Like this:

Like Loading...

Related

Filed Under: Coding

Alex

Reader Interactions

Leave a ReplyCancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Primary Sidebar

About the author

Alex is an AVP of Engineering currently working at Bukalapak. He is a leader in full-stack technologies. Read More…

Pages

  • Speaking Experience
  • About

Social Profiles

  • LinkedIn
  • Medium
  • ADPList

Recent Posts

  • Interviewing as an Engineering Leader
  • Managing Low Performers
  • Getting Docker, React, .NET Core, Postgres, and Nginx Playing Nice
  • What Makes a Good Software Engineering Manager?
  • “Am I There Yet?” Said an Engineer

Archives

  • January 2025
  • August 2024
  • July 2024
  • October 2023
  • August 2023
  • October 2020
  • May 2020
  • February 2020
  • June 2019
  • March 2019
  • October 2018
  • September 2018
  • August 2018
  • July 2018
  • June 2018
  • May 2018
  • April 2018
  • March 2018
  • February 2018
  • January 2018

Categories

  • Coding
  • Essay
  • Leadership
  • Management
  • Roundtable
  • Strategy

Footer

Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use.
To find out more, including how to control cookies, see here: Cookie Policy

Copyright © 2025

 

Loading Comments...
 

    %d