web-dev-qa-db-fra.com

Comment tester axios en plaisantant

J'ai cette action en réaction

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

Comment tester axios dans ce cas? Jest avoir ce cas d'utilisation sur leur site pour le code async où ils utilisent une fonction fictive mais je ne sais pas si je peux le faire avec axios? ref: https://facebook.github.io/jest/docs/tutorial-async.html

Je l'ai fait jusqu'à présent pour vérifier qu'il renvoie le type correct

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

Je ne sais pas comment transmettre des données factices et vérifier qu'elles sont renvoyées. Cependant, quelqu'un a-t-il des idées?

Merci d'avance

46
Adear

J'ai utilisé axios-mock-adapter. Dans ce cas, le service est décrit dans ./chatbot. Dans l'adaptateur factice, vous spécifiez ce qu'il faut retourner lorsque le point de terminaison de l'API est utilisé.

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

Vous pouvez voir tout l'exemple ici:

Service: 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

43
Luis Nolazco

Sans utiliser d'autres bibliothèques:

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

Il est possible de spécifier le code de réponse:

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

Il est possible de changer la maquette en fonction des paramètres:

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

Jest v23 a introduit du sucre syntaxique pour se moquer des promesses:

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

peut être simplifié à

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

Il existe également un équivalent pour les promesses rejetées: mockRejectedValue.

Voir Jest se moquer de la documentation pour plus d'informations. Cette discussion GitHub explique la portée de la ligne jest.mock("axios").

39
A Jar of Clay

Je pourrais le faire en suivant les étapes:

  1. Créer un dossier __ mocks __ / (comme indiqué par @Januartha commenter)
  2. Implémenter un fichier fictif axios.js
  3. Utiliser mon module implémenté sur test

La maquette va se passer automatiquement

Exemple de module simulé:

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

Je l'ai fait avec nock , comme suit:

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...
    })
})
2
Jon B

Pour ceux qui cherchent à utiliser axios-mock-adapter à la place de l'exemple mockfetch dans la documentation de redux pour les tests asynchrones , j'ai utilisé avec succès les éléments suivants

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

});

Afin de tester un cas réussi pour signInUser dans 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
  }
}

Etant donné que cela se fait avec plaisanterie, il a fallu se moquer de l’appel de stockage local. C'était dans src/setupTests.js:

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