Как я могу проверить аксиомы в шутку

У меня есть это действие в реакции

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

Как мне проверить axios в этом случае? Jest есть этот вариант использования на сайте для асинхронного кода, где они используют фиктивную функцию, но я не знаю, смогу ли я сделать это с помощью axios? ref: https://facebook.github.io/jest/docs/tutorial-async.html

Я сделал это до сих пор, чтобы проверить, что он возвращает правильный тип

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

Я понятия не имею, как передать ложные данные и проверить, что они возвращаются, но есть ли у кого-нибудь идеи?

заранее спасибо

Ответ 1

Я использовал axios-mock-adapter. В этом случае услуга описана в. /chatbot. В адаптере mock вы указываете, что нужно вернуть, когда потребляется конечная точка 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

Ответ 2

Без использования других библиотек:

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 представил немного синтаксического сахара для насмешливых обещаний:

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

можно упростить до

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

Существует также эквивалент отклоненных обещаний: mockRejectedValue.

См. Документы по издевке над шутками для получения дополнительной информации. Это обсуждение GitHub объясняет область действия строки jest.mock("axios").

Ответ 3

Я мог бы сделать это, выполнив следующие шаги:

  1. Создайте папку __mocks __/ (как указано в комментарии @Januartha)
  2. axios.js файл axios.js mock
  3. Использовать мой реализованный модуль при тестировании

Макет будет происходить автоматически

Пример модуля макета:

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

Ответ 4

Я сделал это с 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...
    })
})

Ответ 5

Для тех, кто хочет использовать axios-mock-adapter вместо примера mockfetch в документации redux для асинхронного тестирования, я успешно использовал следующие

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

});

Чтобы проверить успешный случай для 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
  }
}

Учитывая, что это делается со шуткой, вызов localstorage должен был насмехаться. Это было в src/setupTests.js:

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