如何在componentDidMount中用笑话测试2个异步调用?

时间:2019-09-24 14:46:10

标签: reactjs jestjs enzyme

我在componentDidMount中有这样的代码:

async componentDidMount() {
    window.scrollTo(0, 0);
    try {
      // check if user has auto
      const { vehicles: auto } = await api.getVehicles();

      const items = auto.filter((car) => car.active);

      if (items.length) {
        this.setActiveAuto(items);
      } else {
        const { name } = await api.getCurrentMoto();

        this.setState({
          name
        });
      }
    } catch (err) {
      console.log(err);
    }
  }

我想在getCurrentMoto()中测试正确的状态更新,所以我写了这样的测试:

const motoResponse = {
  name: 'Honda'
};

const autoResponse = {
  vehicles: [],
};

jest.mock('../api/api.js');

describe('<Component /> Component render', () => {

  let wrapper;

  beforeEach(() => {
    api.getVehicles.mockResolvedValueOnce(autoResponse);
    api.getCurrentMoto.mockResolvedValueOnce(motoResponse);

    wrapper = shallow(<Component />);
  });



    test('correct data passed from endpoint to state in componentDidMount', () => {
      expect(wrapper.state().name).toBe('Honda');
    });


});

但是我的测试失败了

Expected: "Honda"
Received: ""

被嘲笑的api.getCurrentMoto.mockResolvedValueOnce(motoResponse);似乎没有调用,我无法理解如何解决该问题或更改测试以测试componentDidMount中正确的状态更新

1 个答案:

答案 0 :(得分:0)

这是解决方案:

index.tsx

import React, { Component } from 'react';
import { api } from './api';

class XComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      name: ''
    };
  }
  public async componentDidMount() {
    console.log('componentDidMount');
    window.scrollTo(0, 0);
    try {
      // check if user has auto
      const { vehicles: auto } = await api.getVehicles();

      const items = auto.filter(car => car.active);

      if (items.length) {
        this.setActiveAuto(items);
      } else {
        const { name } = await api.getCurrentMoto();

        this.setState({
          name
        });
      }
    } catch (err) {
      console.log(err);
    }
  }

  public setActiveAuto(items) {
    //
  }

  public render() {
    return <div>58082922</div>;
  }
}

export default XComponent;

api.ts

export const api = {
  async getVehicles() {
    return { vehicles: [{ active: true }] };
  },

  async getCurrentMoto() {
    return { name: 'real name' };
  }
};

index.spec.tsx

import React from 'react';
import XComponent from './';
import { api } from './api';
import { shallow } from 'enzyme';

jest.mock('./api.ts');
window.scrollTo = jest.fn();

const motoResponse = {
  name: 'Honda'
};

const autoResponse = {
  vehicles: []
};

describe('<Component /> Component render', () => {
  let wrapper;

  beforeEach(() => {
    (api.getVehicles as any).mockResolvedValueOnce(autoResponse);
    (api.getCurrentMoto as any).mockResolvedValueOnce(motoResponse);

    wrapper = shallow(<XComponent />);
  });

  test('correct data passed from endpoint to state in componentDidMount', done => {
    expect.assertions(5);
    expect(wrapper.text()).toBe('58082922');
    setImmediate(() => {
      expect(api.getVehicles).toBeCalledTimes(1);
      expect(api.getCurrentMoto).toBeCalledTimes(1);
      expect(window.scrollTo).toBeCalledWith(0, 0);
      expect(wrapper.state().name).toBe('Honda');
      done();
    });
  });
});

带有覆盖率报告的单元测试结果:

 PASS  src/stackoverflow/58082922/index.spec.tsx
  <Component /> Component render
    ✓ correct data passed from endpoint to state in componentDidMount (43ms)

  console.log src/stackoverflow/58082922/index.tsx:4305
    componentDidMount

-----------|----------|----------|----------|----------|-------------------|
File       |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files  |    81.48 |       80 |       50 |    82.61 |                   |
 api.ts    |    33.33 |      100 |        0 |    33.33 |               3,7 |
 index.tsx |     87.5 |       80 |    66.67 |       90 |             21,30 |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        6.908s, estimated 11s

源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58082922