Javascript 我如何在玩笑中测试 axios

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/45016033/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 02:51:52  来源:igfitidea点击:

How do I test axios in jest

javascriptreactjsreact-reduxjestjs

提问by Adear

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

在这种情况下如何测试 axios?Jest 在那里有异步代码的用例,他们使用模拟函数,但我不知道我是否可以用 axios 做到这一点?参考: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

先感谢您

采纳答案by Luis Nolazco

I used axios-mock-adapter. In this case the service is described in ./chatbot. In the mock adapter you specify what to return when the API endpoint is consumed.

我使用了 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();
        });
    });
});

You can see it the whole example here:

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

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

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

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

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

回答by A Jar of Clay

Without using any other libraries:

不使用任何其他库:

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({ ... }));
  // ...
});

It is possible to specify the response code:

可以指定响应代码:

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

It is possible to change the mock based on the parameters:

可以根据参数更改模拟:

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

Jest v23 introduced some syntactic sugar for mocking Promises:

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

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

can be simplified to

可以简化为

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

There is also an equivalent for rejected promises: mockRejectedValue.

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

See Jest mocking docsfor more info. This GitHub discussionexplains about the scope of the jest.mock("axios")line.

有关更多信息,请参阅Jest 模拟文档。这个GitHub 讨论解释了该jest.mock("axios")行的范围。

回答by Amadeu Cavalcante Filho

I could do that following the steps:

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

  1. Create a folder __mocks__/(as pointed by @Januartha comment)
  2. Implement an axios.jsmock file
  3. Use my implemented module on test
  1. 创建一个文件夹__mocks__/(如@Januartha 评论所指出的)
  2. 实现一个axios.js模拟文件
  3. 测试中使用我实现的模块

The mock will happen automatically

模拟将自动发生

Example of the mock 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;
    })
};

回答by Jon B

I've done this with nock, like so:

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

回答by vapurrmaid

For those looking to use axios-mock-adapter in place of the mockfetch example in the redux documentation for async testing, I successfully utilized the following

对于那些希望使用 axios-mock-adapter 代替 redux 文档中的 mockfetch 示例进行异步测试的人,我成功地利用了以下内容

actions.test.js:

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: '[email protected]', 
        password: 'test'
    }).reply(200, {token: 'testToken' });

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

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

});

In order to test a successful case for signInUserin actions/index.js:

为了测试signInUserin的成功案例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
  }
}

Given that this is being done with jest, the localstorage call had to be mocked. This was in src/setupTests.js:

鉴于这是开玩笑的,localstorage 调用必须被嘲笑。这是在src/setupTests.js

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