我如何在 Jest 中测试 axios?

IT技术 javascript reactjs react-redux axios jestjs
2021-01-25 13:35:26

我在 React 中有这个动作:

export function fetchPosts() {
    const request = axios.get(`${WORDPRESS_URL}`);
    return {
        type: FETCH_POSTS,
        payload: request
    }
}

在这种情况下如何测试Axios

Jest 在他们的网站上有这个用例,用于异步代码,他们使用模拟函数,但我可以用 Axios 做到这一点吗?

参考:异步示例

到目前为止,我已经这样做以测试它是否返回正确的类型:

it('should dispatch actions with the correct type', () => {
    store.dispatch(fetchPosts());
    let action = store.getActions();
    expect(action[0].type).toBe(FETCH_POSTS);
});

如何传入模拟数据并测试它是否返回?

6个回答

不使用任何其他库:

import * as axios from "axios";

// Mock out all top level functions, such as get, put, delete and post:
jest.mock("axios");

// ...

test("good response", () => {
  axios.get.mockImplementation(() => Promise.resolve({ data: {...} }));
  // ...
});

test("bad response", () => {
  axios.get.mockImplementation(() => Promise.reject({ ... }));
  // ...
});

可以指定响应代码:

axios.get.mockImplementation(() => Promise.resolve({ status: 200, data: {...} }));

可以根据参数更改模拟:

axios.get.mockImplementation((url) => {
    if (url === 'www.example.com') {
        return Promise.resolve({ data: {...} });
    } else {
        //...
    }
});

Jest v23 引入了一些用于模拟 Promise 的语法糖:

axios.get.mockImplementation(() => Promise.resolve({ data: {...} }));

可以简化为

axios.get.mockResolvedValue({ data: {...} });

拒绝的Promise也有一个等价物:mockRejectedValue.

进一步阅读:

我使用了axios-mock-adapter在这种情况下,服务在 ./chatbot 中描述。在模拟适配器中,您指定使用 API 端点时要返回的内容。

import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import chatbot from './chatbot';

describe('Chatbot', () => {
    it('returns data when sendMessage is called', done => {
        var mock = new MockAdapter(axios);
        const data = { response: true };
        mock.onGet('https://us-central1-hutoma-backend.cloudfunctions.net/chat').reply(200, data);

        chatbot.sendMessage(0, 'any').then(response => {
            expect(response).toEqual(data);
            done();
        });
    });
});

您可以在此处查看整个示例:

服务:https : //github.com/lnolazco/hutoma-test/blob/master/src/services/chatbot.js

测试:https : //github.com/lnolazco/hutoma-test/blob/master/src/services/chatbot.test.js

如果我不想模拟 axios,而是希望它提出真正的请求怎么办?
2021-04-11 13:35:26

我可以按照以下步骤执行此操作:

  1. 创建一个文件夹__mocks__/(如@Januartha 评论指出的那样)
  2. 实现一个axios.js模拟文件
  3. 测试中使用我实现的module

模拟将自动发生

模拟module示例:

module.exports = {
    get: jest.fn((url) => {
        if (url === '/something') {
            return Promise.resolve({
                data: 'data'
            });
        }
    }),
    post: jest.fn((url) => {
        if (url === '/something') {
            return Promise.resolve({
                data: 'data'
            });
        }
        if (url === '/something2') {
            return Promise.resolve({
                data: 'data2'
            });
        }
    }),
    create: jest.fn(function () {
        return this;
    })
};
嗨@shorif2000 我在这里实现了它github.com/vspedr/movile-messaging/pull/8/files
2021-03-17 13:35:26
@AmadeuCavalcanteFilho 啊当然,没问题:)
2021-04-09 13:35:26
里面写手动嘲弄嘲弄是不是一个好的做法是手动嘲笑文件说要编写内部手册嘲笑__mocks__
2021-04-11 13:35:26
@Januartha 抱歉,我打错了字。我要在这里更正它。我输入了“____mock___”的回复,它把我的话加粗了。对不起
2021-04-11 13:35:26

我已经用nock完成了这个,就像这样:

import nock from 'nock'
import axios from 'axios'
import httpAdapter from 'axios/lib/adapters/http'

axios.defaults.adapter = httpAdapter

describe('foo', () => {
    it('bar', () => {
        nock('https://example.com:443')
            .get('/example')
            .reply(200, 'some payload')

        // test...
    })
})
nock 是在测试中处理 http 调用的最佳方式
2021-03-21 13:35:26
我确实尝试过这个,但我似乎 axios 不能很好地与 nock 配合使用。github.com/node-nock/nock/issues/699但仍然感谢您的帮助
2021-04-10 13:35:26

看这个

  1. 要测试的功能 album.js
const fetchAlbum = function () {
 return axios
   .get("https://jsonplaceholder.typicode.com/albums/2")
   .then((response) => {
     return response.data;
   });
};
  1. 考试 album.test.js
const axios = require("axios");
const { fetchAlbum } = require("../utils.js");

jest.mock("axios");

test("mock axios get function", async () => {
    expect.assertions(1);
    const album = {
      userId: 1,
      id: 2,
      title: "sunt qui excepturi placeat culpa",
    };
    const payload = { data: album };
    // Now mock axios get method
    axios.get = jest.fn().mockResolvedValue(payload);
    await expect(fetchAlbum()).resolves.toEqual(album);
  });