如何通过实例在Jest中测试Axios(附代码)

1,085 阅读2分钟

每隔一段时间,我们就需要测试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获取数据的例子中,我们向函数提供一个查询参数,以便通过其APIHacker 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模拟例子。还有一些想法: