如何使用 Jest 和 Enzyme 测试 componentDidMount() 中的方法?

How to test a method in componentDidMount() with Jest and Enzyme?

我想用单元测试覆盖下面的代码:

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());
}
}

并开始用下面的测试覆盖 componentDidMount

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
});

但我收到错误消息: Argument of type '"setData"' is not assignable to parameter of type 'FunctionPropertyNames<Required<DataTrack>>'.

我也不知道如何使用 Jest/Enzyme.

测试方法 setDatagetDatapushData

有人可以帮我解决这个问题吗? 如何覆盖 componentDidMount 中的方法和自身的方法?

您可以测试 window.globalDatawindow.analyticsData 是否设置了正确的值。私有方法不需要安装间谍。

此外,您应该将window.globalDatawindow.analyticsData属性恢复到初始状态。避免测试用例相互影响。

例如

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();
  });
});

测试结果:

 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