How do I test axios in jest

时间:2017-07-10 15:28:50

标签: reactjs react-redux jestjs

I have this action in react

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

How do I test axios in this case? Jest have this use case on there site for async code where they use a mock function but I don't know if I can do this with axios? ref: https://facebook.github.io/jest/docs/tutorial-async.html

I have done this so far to test that it is returning the correct type

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

I have no idea how to pass in mock data and test that it returns however, has anyone got any ideas?

Thank you in advance

6 个答案:

答案 0 :(得分:35)

我使用了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

答案 1 :(得分:30)

不使用任何其他库:

import * as axios from "axios";

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

// ...

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

it("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 mocking docs

答案 2 :(得分:15)

我可以按照以下步骤做到:

  1. 创建一个文件夹 __ mocks __ / (由@Januartha评论指出)
  2. 实施axios.js模拟文件
  3. 测试
  4. 上使用我实施的模块

    模拟将自动发生

    模拟模块的示例:

    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;
        })
    };
    

答案 3 :(得分:2)

我已使用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...
    })
})

答案 4 :(得分:0)

对于那些希望使用axios-mock-adapter代替redux文档for async testing中的mockfetch示例的人,我成功地使用了以下

actions.test.js

describe('SignInUser', () => {
  var history = {
    push: function(str) {
        expect(str).toEqual('/feed');
    }
  }

  it('Dispatches authorization', () => {
    let mock = new MockAdapter(axios);
    mock.onPost(`${ROOT_URL}/auth/signin`, { 
        email: 'test@test.com', 
        password: 'test'
    }).reply(200, {token: 'testToken' });

    const expectedActions = [ { type: types.AUTH_USER } ];
    const store = mockStore({ auth: [] });

    return store.dispatch(actions.signInUser({ 
      email: 'test@test.com', 
      password: 'test',
    }, history)).then(() => {
        expect(store.getActions()).toEqual(expectedActions);
  });

});

为了在signInUser中测试actions/index.js的成功案例:

export const signInUser = ({ email, password }, history) => async dispatch => {
  const res = await axios.post(`${ROOT_URL}/auth/signin`, { email, password })
    .catch(({ response: { data } }) => {
        ...
  });

  if (res) {
    dispatch({ type: AUTH_USER });                 // test verified this
    localStorage.setItem('token', res.data.token); // test mocked this
    history.push('/feed');                         // test mocked this
  }
}

鉴于这是用jest完成的,必须嘲笑localstorage调用。这是在src/setupTests.js

const localStorageMock = {
  removeItem: jest.fn(),
  getItem: jest.fn(),
  setItem: jest.fn(),
  clear: jest.fn()
};
global.localStorage = localStorageMock;

答案 5 :(得分:0)

看看这个

  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);
  });