每隔一段时间,我们就需要测试API请求。Axios是最流行的JavaScript库之一,用于从远程API获取数据。因此,我们将使用Axios作为我们的数据获取例子--然而,下面的教程应该可以使axios与任何其他数据获取库交换。
import axios from 'axios';
export const API = 'https://hn.algolia.com/api/v3';
export const fetchData = async query => {
const url = `${API}/search?query=${query}`;
return await axios.get(url);
};
fetchData('react');
在这个用axios获取数据的例子中,我们向函数提供一个查询参数,以便通过其API在Hacker News上进行搜索。如果请求成功,我们将返回响应。如果请求遇到了网络错误,该函数将抛出一个错误,我们必须在其外部捕获该错误。
现在我们要使用Jest来测试异步数据获取函数。Jest被用作测试运行器(替代方案:Mocha),但也被用作断言工具(替代方案:Chai)。此外,它还带有监视、存根和模拟(异步)函数的实用程序。这就是我们将如何使用Jest来模拟Axios。
import { fetchData } from './';
describe('fetchData', () => {
it('fetches successfully data from an API', async () => {
});
it('fetches erroneously data from an API', async () => {
});
});
首先,我们将用Jest模拟Axios。其次,我们将给Axios的get方法一个模拟实现,为两个测试解决和拒绝一个承诺:
import axios from 'axios';
import { fetchData } from './';
jest.mock('axios');
describe('fetchData', () => {
it('fetches successfully data from an API', async () => {
const data = {
data: {
hits: [
{
objectID: '1',
title: 'a',
},
{
objectID: '2',
title: 'b',
},
],
},
};
axios.get.mockImplementationOnce(() => Promise.resolve(data));
});
it('fetches erroneously data from an API', async () => {
const errorMessage = 'Network Error';
axios.get.mockImplementationOnce(() =>
Promise.reject(new Error(errorMessage)),
);
});
});
最后但并非最不重要的是,我们将在成功或错误地解决承诺的情况下用Jest做出断言:
import axios from 'axios';
import { fetchData } from './';
jest.mock('axios');
describe('fetchData', () => {
it('fetches successfully data from an API', async () => {
const data = {...};
axios.get.mockImplementationOnce(() => Promise.resolve(data));
await expect(fetchData('react')).resolves.toEqual(data);
});
it('fetches erroneously data from an API', async () => {
const errorMessage = 'Network Error';
axios.get.mockImplementationOnce(() =>
Promise.reject(new Error(errorMessage)),
);
await expect(fetchData('react')).rejects.toThrow(errorMessage);
});
});
作为奖励,我们还可以断言Axios的get已经被正确的URL调用:
import axios from 'axios';
import { fetchData, API } from './';
jest.mock('axios');
describe('fetchData', () => {
it('fetches successfully data from an API', async () => {
const data = {...};
axios.get.mockImplementationOnce(() => Promise.resolve(data));
await expect(fetchData('react')).resolves.toEqual(data);
expect(axios.get).toHaveBeenCalledWith(
`${API}/search?query=react`,
);
});
...
});
这就是通过一个例子为Axios创建Jest mock的过程。你可以在GitHub资源库中找到这个Axios的Jest模拟例子。还有一些想法:
axios.post如果你想模拟一个帖子而不是Axios的获取请求,只需应用mockImplementationOnce(),而不是axios.get。- 如果你想有一个适当的网络错误,例如状态代码404,那么你必须为它创建一个自定义的JavaScript错误。
- 最后,如果你想看看如何用Jest和Enzyme在React中测试Axios的数据获取,可以去看看这个教程。