如何使用Jest测试Ajax调用?

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

标签: reactjs jestjs

我想使用Jest测试以下代码。

class Login extends React.Component {
    getData() {
        $.ajax({
            type: "GET",
            url: myURL,
            success: function(data) {
                //some stuff with data
            },
            error :function(){
                alert("ERROR");
            }
        });
    }

    render() {
        return(
            //some stuff
        );
    }
}
export default Login;

如何使用玩笑来测试Ajax调用? 我还想要上面代码的代码覆盖率报告。

谢谢。

1 个答案:

答案 0 :(得分:0)

这是我的解决方案,我为您的代码做了一些重构,以便于测试。

index.tsx,组件代码:

import React from 'react';
import $ from 'jquery';

class Login extends React.Component {
  constructor(props) {
    super(props);
    this.handleError = this.handleError.bind(this);
    this.handleSuccess = this.handleSuccess.bind(this);
  }
  public getData() {
    const myURL = 'https://github.com/mrdulin';
    $.ajax({
      type: 'GET',
      url: myURL,
      success: this.handleSuccess,
      error: this.handleError
    });
  }

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

  private handleSuccess(data) {
    console.log(data);
  }

  private handleError() {
    alert('ERROR');
  }
}
export default Login;

index.spec.tsx,使用jestjsenzyme的单元测试

import React from 'react';
import Login from './';
import $ from 'jquery';
import { shallow } from 'enzyme';

describe('Login', () => {
  afterEach(() => {
    jest.restoreAllMocks();
  });
  test('should get data', async () => {
    const ajaxSpy = jest.spyOn($, 'ajax');
    const wrapper = shallow(<Login></Login>);
    const instance = wrapper.instance();
    (instance as any).getData();
    expect(wrapper.text()).toBe('Login');
    expect(ajaxSpy).toBeCalledWith({
      type: 'GET',
      url: 'https://github.com/mrdulin',
      // tslint:disable-next-line: no-string-literal
      success: instance['handleSuccess'],
      // tslint:disable-next-line: no-string-literal
      error: instance['handleError']
    });
  });

  test('handleSuccess', () => {
    const logSpy = jest.spyOn(console, 'log');
    const wrapper = shallow(<Login></Login>);
    const instance = wrapper.instance();
    // tslint:disable-next-line: no-string-literal
    instance['handleSuccess']('some data');
    expect(logSpy).toBeCalledWith('some data');
  });

  test('handleError', () => {
    window.alert = jest.fn();
    const wrapper = shallow(<Login></Login>);
    const instance = wrapper.instance();
    // tslint:disable-next-line: no-string-literal
    instance['handleError']();
    expect(window.alert).toBeCalledWith('ERROR');
  });
});

覆盖率100%的单元测试结果:

 PASS  src/stackoverflow/58306745/index.spec.tsx (8.183s)
  Login
    ✓ should get data (27ms)
    ✓ handleSuccess (3ms)
    ✓ handleError (1ms)

some data
-----------|----------|----------|----------|----------|-------------------|
File       |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files  |      100 |      100 |      100 |      100 |                   |
 index.tsx |      100 |      100 |      100 |      100 |                   |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        9.545s

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