Home > Back-end >  How to test a method in componentDidMount() with Jest and Enzyme?
How to test a method in componentDidMount() with Jest and Enzyme?

Time:12-18

I want to cover the code below with unit test:

export class DataTrack extends Component<DataTrackProps> {
componentDidMount() {
    this.setData();
    
    if (this.props.enableDataTrack) {
        this.pushData();
    }
}

private setData() {
    window.globalData = {
        app_platform        : "I"
    }
}

private getData() {
        this.dataTrack= {
            command: "EVENT",
            name: "data",
            data: {
                app_embed_name : "it"
            }
        };

        return this.dataTrack;
}

private pushData() {
    window.analyticsData = window.analyticsData || [];
    window.analyticsData .push(this.getData());
}
}

and started with covering the componentDidMount with the test below:

it("should run the methods in the componentDidMount", () => {
    const props: DataTrackProps= {
        enableDataTrack: true,
    };

    const setDataOnMount = jest.spyOn(DataTrack.prototype, 'setData'); // spy
    const wrapper = shallow(<DataTrack{...props}  />); // create
    expect(setDataOnMount ).toHaveBeenCalledTimes(1); // test
});

But I'm getting the error: Argument of type '"setData"' is not assignable to parameter of type 'FunctionPropertyNames<Required<DataTrack>>'.

I also don't know how to test the methods setData, getData and pushData with Jest/Enzyme.

Can someone help me with this? How can I cover the methods inside the componentDidMount and the methods self?

CodePudding user response:

You can test if the window.globalData and window.analyticsData are set with the correct value. There is no need to install spy to the private methods.

Besides, you should restore window.globalData and window.analyticsData property to the initial state. Avoid test cases influencing each other.

E.g.

DataTrack.tsx:

import React, { Component } from 'react';

declare global {
  interface Window {
    globalData: any;
    analyticsData: any;
  }
}

interface DataTrackProps {
  enableDataTrack?: boolean;
}
export class DataTrack extends Component<DataTrackProps> {
  dataTrack = {};
  componentDidMount() {
    this.setData();
    if (this.props.enableDataTrack) {
      this.pushData();
    }
  }

  private setData() {
    window.globalData = { app_platform: 'I' };
  }

  private getData() {
    this.dataTrack = {
      command: 'EVENT',
      name: 'data',
      data: {
        app_embed_name: 'it',
      },
    };
    return this.dataTrack;
  }

  private pushData() {
    window.analyticsData = window.analyticsData || [];
    window.analyticsData.push(this.getData());
  }
  render() {
    return <div>data track</div>;
  }
}

DataTract.test.tsx:

import { shallow } from 'enzyme';
import React from 'react';
import { DataTrack } from './DataTract';

describe('DataTract', () => {
  afterEach(() => {
    window.globalData = undefined;
    window.analyticsData = undefined;
  });
  test('should push and set data', () => {
    shallow(<DataTrack enableDataTrack />);
    expect(window.globalData).toEqual({ app_platform: 'I' });
    expect(window.analyticsData).toEqual([
      {
        command: 'EVENT',
        name: 'data',
        data: {
          app_embed_name: 'it',
        },
      },
    ]);
  });

  test('should set data', () => {
    shallow(<DataTrack enableDataTrack={false} />);
    expect(window.globalData).toEqual({ app_platform: 'I' });
    expect(window.analyticsData).toBeUndefined();
  });
});

test result:

 PASS  examples/70364599/DataTract.test.tsx (8.509 s)
  DataTract
    ✓ should push and set data (5 ms)
    ✓ should set data

---------------|---------|----------|---------|---------|-------------------
File           | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
---------------|---------|----------|---------|---------|-------------------
All files      |     100 |      100 |     100 |     100 |                   
 DataTract.tsx |     100 |      100 |     100 |     100 |                   
---------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        9.315 s, estimated 10 s
  • Related