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
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
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")
.
Je pourrais le faire en suivant les étapes:
axios.js
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;
})
};
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...
})
})
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;