如何在异步componentDidMount axios调用中测试正确的状态更新?

时间:2019-05-23 18:39:24

标签: javascript reactjs jestjs enzyme

我的异步/等待生命周期如下

var arr1 = [ [0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 2] ];
var arr2 = [ [0, 1], [0, 0], [2, 2] ];

var commonValueIndex = [];
for (var i = 0; i < arr1.length; i++) {
  for (var j = 0; j < arr2.length; j++) {
    if (arr1[i][0] == arr2[j][0] && arr1[i][1] == arr2[j][1]) {
      // if you want the actual values
      commonValueIndex.push([arr1[i][0], arr1[i][1]]);
      // if you want the indices
      // commonValueIndex.push([i, j]);
    }
  }
}
console.log(commonValueIndex);

我编写了以下测试以测试在数据来自等待调用时正确更新的状态:

// Pig Latin

const pigify = (str) => {

  let sentSplit = str.split(' ')
  //console.log(sentSplit)

  for (let i=0; i<sentSplit.length; i++){
    //console.log(sentSplit[i])
    let element = sentSplit[i]

    console.log(element[0])

    if (element[0].includes('a', 'e', 'i', 'o', 'u')){
      return `${element}ay`
    }

    // else if (!str[0].includes('a', 'e', 'i', 'o', 'u') && !str[1].includes('a', 'e', 'i', 'o', 'u')){
    //   return `${str.slice(2)}${str.slice(0,2)}ay`
    // }

    // else if(!str[0].includes('a', 'e', 'i', 'o', 'u')){
    //   return `${str.slice(1)}${str[0]}ay`
    // }
  }
}

pigify('eat')

但是测试运行时出现错误:

async componentDidMount() {
    try {
      const { name, key, expiration } = await DataService.getdata();
      this.setState({
        key,
        expiration,
        name,
      });
    } catch (err) {
      console.log(err);
    }
  }

测试永远不会结束,它将继续运行

如果我删除此测试并仅运行测试以正确渲染,则会出现以下错误:

jest.mock("axios");

test('correct state update', () => {
      const responseText = {
        name: "test name",
        key: "test_key",
        expiration: null,
      };
      axios.get.mockResolvedValueOnce(responseText);
      const wrapper = shallow(<ComponentWrapper />);

      setImmediate(() => {
        expect(wrapper.state().name).toBe('test name');
        done();
      });
    });

1 个答案:

答案 0 :(得分:0)

这是解决方案:

index.ts

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

interface ISomeComponentState {
  name: string;
  key: string;
  expiration: string | null;
}

export class SomeComponent extends Component<any, ISomeComponentState> {
  constructor(props) {
    super(props);
    this.state = {
      name: '',
      key: '',
      expiration: ''
    };
  }

  public async componentDidMount() {
    try {
      const { name, key, expiration } = await DataService.getdata();
      this.setState({ key, expiration, name });
    } catch (err) {
      console.log(err);
    }
  }

  public render() {
    const { name, key, expiration } = this.state;
    return (
      <div>
        key: {key}, name: {name}, expiration: {expiration}
      </div>
    );
  }
}

DataService.ts

import axios from 'axios';

class DataService {
  public static async getdata() {
    return axios.get(`https://github.com/mrdulin`).then(() => {
      return {
        name: 'real name',
        key: 'real key',
        expiration: null
      };
    });
  }
}

export { DataService };

单元测试:

import React from 'react';
import { shallow } from 'enzyme';
import { SomeComponent } from './';
import { DataService } from './DataService';

jest.mock('./DataService.ts');

DataService.getdata = jest.fn();

describe('SomeComponent', () => {
  const responseText = {
    name: 'test name',
    key: 'test_key',
    expiration: null
  };
  it('correct state update', done => {
    (DataService.getdata as jest.MockedFunction<typeof DataService.getdata>).mockResolvedValueOnce(responseText);
    const wrapper = shallow(<SomeComponent></SomeComponent>);
    setImmediate(() => {
      expect(wrapper.state('name')).toBe(responseText.name);
      done();
    });
  });
});

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

 PASS  src/stackoverflow/56281185/index.spec.tsx (5.697s)
  SomeComponent
    ✓ correct state update (24ms)

----------------|----------|----------|----------|----------|-------------------|
File            |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------------|----------|----------|----------|----------|-------------------|
All files       |    88.46 |      100 |    71.43 |       85 |                   |
 DataService.ts |    71.43 |      100 |    33.33 |    71.43 |               5,6 |
 index.tsx      |    94.74 |      100 |      100 |    92.31 |                25 |
----------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        6.582s

以下是完整的演示:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/56281185