首页 > 解决方案 > 使用 jest 对 axios post 进行单元测试

问题描述

我正在使用 jest 编写单元测试。我该如何测试axios.post?我查看了所有内容,但几乎每个人都有使用示例,axios.get但没有使用帖子。

 handleLogout(event) {
    event.preventDefault();
    axios
      .post("/logout")
      .then(function(response) {
        window.location = "/login";
      })
      .catch(function(error) {
        console.log(error);
      });

此方法由按钮onclick事件触发。

<button
    type="button"
    value="Logout"
    onClick={this.handleLogout}
  >
    Logout
  </button>

我怎样才能开玩笑地为这个场景编写一个测试用例?

编辑1:

  it("testing for axios", () => {
wrapper.simulate(
  "click",
  {
    preventDefault: () => {}
  },
);
console.log("here");
expect.assertions(1);

它给了我错误:

TypeError:_axios2.default.post 不是函数

如果我不模拟阻止默认值,它会给我这个

“TypeError:无法读取未定义的属性‘preventDefault’”。

所以我假设我需要在处理 preventDefault() 之后以某种方式模拟 axios。我在正确的道路上吗?如何解决这个问题?

标签: reactjsjestjsaxios

解决方案


这是解决方案:

index.tsx

import React from 'react';
import axios from 'axios';

export class SomeComponent extends React.Component {
  constructor(props) {
    super(props);
    this.handleLogout = this.handleLogout.bind(this);
  }
  public render() {
    return (
      <div>
        <button type="button" value="Logout" onClick={this.handleLogout}>
          Logout
        </button>
      </div>
    );
  }

  private handleLogout(event: React.MouseEvent<HTMLButtonElement>) {
    event.preventDefault();
    axios
      .post('/logout')
      .then(response => {
        console.log(response);
      })
      .catch(error => {
        console.log(error);
      });
  }
}

单元测试:

index.spec.tsx

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

jest.mock('axios', () => {
  return {
    post: jest.fn()
  };
});

describe('SomeComponent', () => {
  describe('#handleLogout', () => {
    const mockedMouseEvent = {
      preventDefault: jest.fn()
    };
    it('should logout correctly', done => {
      const mockedData = 'mocked data';
      const wrapper = shallow(<SomeComponent></SomeComponent>);
      expect(wrapper.find('button')).toHaveLength(1);
      (axios.post as jest.MockedFunction<typeof axios.post>).mockResolvedValueOnce(mockedData);
      const consoleLogSpyOn = jest.spyOn(console, 'log');

      wrapper.find('button').simulate('click', mockedMouseEvent);
      expect(wrapper.find('button').text()).toBe('Logout');
      expect(axios.post).toBeCalledWith('/logout');

      setImmediate(() => {
        expect(consoleLogSpyOn).toBeCalledWith(mockedData);
        consoleLogSpyOn.mockRestore();
        done();
      });
    });

    it('should throw error when axios post error', done => {
      const mockedError = new Error('network error');
      const wrapper = shallow(<SomeComponent></SomeComponent>);
      expect(wrapper.find('button')).toHaveLength(1);
      (axios.post as jest.MockedFunction<typeof axios.post>).mockRejectedValueOnce(mockedError);
      const consoleLogSpyOn = jest.spyOn(console, 'log');
      wrapper.find('button').simulate('click', mockedMouseEvent);
      expect(wrapper.find('button').text()).toBe('Logout');
      expect(axios.post).toBeCalledWith('/logout');

      setImmediate(() => {
        expect(consoleLogSpyOn).toBeCalledWith(mockedError);
        consoleLogSpyOn.mockRestore();
        done();
      });
    });
  });
});

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

 PASS  src/stackoverflow/54555039/index.spec.tsx
  SomeComponent
    #handleLogout
      ✓ should logout correctly (29ms)
      ✓ should throw error when axios post error (14ms)

  console.log node_modules/jest-mock/build/index.js:860
    mocked data

  console.log node_modules/jest-mock/build/index.js:860
    Error: network error
        at Object.<anonymous> (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/54555039/index.spec.tsx:36:27)
        at resolve (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/node_modules/jest-jasmine2/build/queueRunner.js:43:12)
        at new Promise (<anonymous>)
        at mapper (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/node_modules/jest-jasmine2/build/queueRunner.js:26:19)
        at promise.then (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/node_modules/jest-jasmine2/build/queueRunner.js:73:41)

-----------|----------|----------|----------|----------|-------------------|
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:       2 passed, 2 total
Snapshots:   0 total
Time:        4.483s, estimated 5s

这是完成的演示:https ://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/54555039


推荐阅读