javascript - Jest'te axios'u nasıl test ederim?
React'te bu aksiyona sahibim:
export function fetchPosts() {
const request = axios.get(`${WORDPRESS_URL}`);
return {
type: FETCH_POSTS,
payload: request
}
}
Bu durumda Axios'u nasıl test edebilirim?
Jest'in sitesinde, sahte bir fonksiyon kullandıkları asenkron kod için bu kullanım durumu var, ama bunu Axios ile yapabilir miyim?
Referans: Asenkron Bir Örnek
Şu ana kadar bunu, doğru türü döndürdüğünü test etmek için yaptım:
it('should dispatch actions with the correct type', () => {
store.dispatch(fetchPosts());
let action = store.getActions();
expect(action[0].type).toBe(FETCH_POSTS);
});
Sahte verileri nasıl geçirebilir ve bunun döndüğünü nasıl test edebilirim?
Cevap #1
Başka herhangi bir kütüphane kullanmadan:
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({ ... }));
// ...
});
Yanıt kodunu belirtmek mümkündür:
axios.get.mockImplementation(() => Promise.resolve({ status: 200, data: {...} }));
Parametrelere bağlı olarak taklidin değiştirilmesi mümkündür:
axios.get.mockImplementation((url) => {
if (url === 'www.example.com') {
return Promise.resolve({ data: {...} });
} else {
//...
}
});
Jest v23, Promise'leri taklit etmek için bazı sentaktik kolaylıklar tanıttı:
axios.get.mockImplementation(() => Promise.resolve({ data: {...} }));
Şuna indirgenebilir
axios.get.mockResolvedValue({ data: {...} });
Reddedilmiş sözler için de bir eşdeğer vardır: mockRejectedValue.
Daha Fazla Okuma:
- Jest taklit etme belgeleri
jest.mock("axios")satırının kapsamını açıklayan bir GitHub tartışması.- Yukarıdaki teknikleri Axios istek kesicilerine uygulamayı ele alan ilgili bir soru.
- TypeScript'te
mockImplementationgibi jest fonksiyonlarını kullanma: TypeScript ve Jest: Mocklanan fonksiyonlarda tip hatalarından kaçınma
Cevap #2
Axios-mock-adapter kullandım. Bu durumda servis ./chatbot içinde tanımlanmıştır. Mock adaptörde, API uç noktası kullanıldığında ne döndürüleceğini belirtiyorsunuz.
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();
});
});
});
Tüm örneği burada görebilirsiniz:
Servis: 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
Cevap #3
Bunu adımları izleyerek yapabilirim:
- __mocks__/ klasörü oluşturun ( @Januartha yorumunda belirtildiği gibi)
axios.jstaklit dosyası oluştur- test üzerinde uyguladığım modülü kullan
Sahte otomatik olarak gerçekleşecek
Sahte modülün örneği:
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;
})
};
Cevap #4
Buna bak
album.jsdosyasını test etmek için fonksiyon
const fetchAlbum = function () {
return axios
.get("https://jsonplaceholder.typicode.com/albums/2")
.then((response) => {
return response.data;
});
};
- Test
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);
});
