本文介绍了如何使用config选项测试axios的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正尝试测试以下针对axios请求而编写的put/post作为配置选项:

I'm trying to test the below axios request written for both put/post as a config option:

export function saveCourse(course){
  const config = {
      method: course.id ? 'PUT' : 'POST',// POST for create, PUT to update when id already exists.
      url: baseUrl + (course.id || ''),
      headers: { "content-type": "application/json" },
      data: course
  }
  return axios(config)
  .then((res) => {
      if(res.status === 201 || res.status === 200) return res.data;
      if(res.status === 400){
          const error = res.text();
          throw new Error(error);
      }
  })
  .catch((err) => console.log(err));  
}

courseApi.test.js看起来像这样:

The courseApi.test.js looks like this:

import { saveCourse } from './courseApi';
import axios from 'axios';

jest.mock('axios');

describe('check API calls', () => {
 it('should update the course', () => {
    let res = {
      id: 10,
      title: "Securing React Apps with Auth0",
      slug: "react-auth0-authentication-security",
      authorId: 2,
      category: "JavaScript"
    };

    const config = {
        method: 'put',
        url: 'http://localhost:3001/courses/10',
        headers: { "content-type": "application/json" },
        data: res
      }
    }

  axios = jest.fn().mockResolvedValue({
        status: 200,
        data: res
      });
      let result = await saveCourse(res);
      expect(result).toEqual(res);
      // expect(axiosMock.put).toHaveBeenCalledTimes(1);
 });
});

同样也尝试过模拟ImplementationOnce,在这种情况下不会调用模拟axios.

Tried with mockImplementationOnce as well, in this case the mock axios is not being called.

it("save course scenario", async function () {
    const course = {
      id: 10,
      title: "Securing React Apps with Auth0",
      slug: "react-auth0-authentication-security",
      authorId: 2,
      category: "JavaScript"
    };
    axios.put.mockImplementationOnce(() => Promise.resolve(course));
    expect(saveCourse(course)).resolves.toEqual(course);
    expect(axios.put).toHaveBeenCalledTimes(1);
    });

抛出错误如下:

 TypeError: Cannot read property 'then' of undefined

      24 |       data: course
      25 |   }
    > 26 |   return axios(config)
         |          ^
      27 |   .then((res) => {
      28 |       if(res.status === 201) { console.log(res); return res.data; }
      29 |       if(res.status === 200) { console.log(res); return res.data; }

      at saveCourse (src/api/courseApi.js:26:10)
      at Object.<anonymous> (src/api/courseApi.test.js:39:12)

那么,如果我错过了为axios模拟设置的任何东西,我该如何解决呢?

So how should i fix this, any thing that i missed to set for axios mocking?

提前谢谢!

推荐答案

单元测试解决方案:

index.js:

import axios from 'axios';

export function saveCourse(course) {
  const baseUrl = 'http://example.com/';
  const config = {
    method: course.id ? 'PUT' : 'POST',
    url: baseUrl + (course.id || ''),
    headers: { 'content-type': 'application/json' },
    data: course,
  };
  return axios(config)
    .then((res) => {
      if (res.status === 201 || res.status === 200) return res.data;
      if (res.status === 400) {
        const error = res.text();
        throw new Error(error);
      }
    })
    .catch((err) => console.log(err));
}

index.test.js:

import { saveCourse } from './';
import axios from 'axios';

jest.mock('axios', () => jest.fn());

describe('60992357', () => {
  afterEach(() => {
    jest.restoreAllMocks();
  });
  it('should return data if status code equals 200', async () => {
    const mRes = { status: 200, data: 'fake data' };
    axios.mockResolvedValueOnce(mRes);
    const actual = await saveCourse({ id: 1 });
    expect(actual).toEqual('fake data');
    expect(axios).toBeCalledWith({
      method: 'PUT',
      url: 'http://example.com/1',
      headers: { 'content-type': 'application/json' },
      data: { id: 1 },
    });
  });

  it('should throw error if status code equals 400', async () => {
    const mRes = { status: 400, text: jest.fn().mockReturnValue('network') };
    axios.mockResolvedValueOnce(mRes);
    const logSpy = jest.spyOn(console, 'log');
    const actual = await saveCourse({ id: 1 });
    expect(actual).toBeUndefined();
    expect(axios).toBeCalledWith({
      method: 'PUT',
      url: 'http://example.com/1',
      headers: { 'content-type': 'application/json' },
      data: { id: 1 },
    });
    expect(mRes.text).toBeCalledTimes(1);
    expect(logSpy).toBeCalledWith(new Error('network'));
  });
});

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

unit test results with coverage report:

 PASS  stackoverflow/60992357/index.test.js (9.916s)
  60992357
    ✓ should return data if status code equals 200 (7ms)
    ✓ should throw error if status code equals 400 (21ms)

  console.log node_modules/jest-environment-enzyme/node_modules/jest-mock/build/index.js:866
    Error: network
        at /Users/ldu020/workspace/github.com/mrdulin/react-apollo-graphql-starter-kit/stackoverflow/60992357/index.js:671:13
        at process._tickCallback (internal/process/next_tick.js:68:7)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |       70 |     100 |     100 |                   
 index.js |     100 |       70 |     100 |     100 | 6,7,14            
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        11.848s

源代码: https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/60992357

这篇关于如何使用config选项测试axios的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 22:57