Ensuring componentDidMount is not called in Unit Tests

If you are building a ReactJs you will often times implement componentDidMount on your components.  This is very handy at runtime, but can pose an issue for unit tests.

If you are building tests for your React app you are very likely using enzyme to create instances of your component.  The issue is that when enzyme creates the component it invokes the lifecyle methods, like componentDidMount.  Sometimes we do not want this to be called, but how to suppress this?

I have found 2 different ways to suppress/mock componentDidMount.

Method one is to redefine componentDidMount on your component for your tests.  This could have interesting side effects so use with caution.

    describe('UsefullNameHere', () => {
        
        beforeAll(() => {
            YourComponent.prototype.componentDidMount = () => {
                // can omit or add custom logic
            };
        });
    });

Basically above I am just redefining the componentDidMount method on my component.  This works and allows you to have custom logic.  Be aware that when doing above you will have changed the implementation for your component for the lifetime of your test session.

Another solution is to use a mocking framework like SinonJs.  With Sinon you can stub out the componentDidMount implementation as seen below

    describe('UsefullNameHere', () => {
        
        let componentDidMountStub = null;
        beforeAll(() => {
            componentDidMountStub = sinon.stub(YourComponent.prototype, 'componentDidMount').callsFake(function() {
                 // can omit or add custom logic
            });
        });

        afterAll(() => {
            componentDidMountStub.restore();
        });
    });

Above I am using .stub to redefine the method.  I also added .callsFake() but this can be omitted if you just want to ignore the call.  You will want to make sure you restore your stub via the afterAll, otherwise you will have stubbed out the call for the lifetime of your test session.

Till next time,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s