如何模拟函数,即axios promise中的“ then”调用?

时间:2019-02-06 11:04:11

标签: javascript mocking jestjs

我有一个函数,该函数从后端获取数据。成功获取后,它将从响应中提取一个值,然后调用另一个函数(parseAllRecordsData),该函数会将值转换为其他值。我正在尝试测试此功能,但是在模拟parseAllRecordsData函数之后,它仍在尝试调用原始函数(并从该函数引发错误)。

在其他测试中,jest.fn或jest.spy可以正常工作,但是当我尝试模拟“ then”中使用的函数时,效果却并非如此。

export function fetchAllRecordsData(payload) {
    const url = `/apis/${payload.link.split('apis/')[1]}`;
    return axios.get(url)
        .then(({ data }) => {
            if (data && data._embedded) {
                const parsedData = data._embedded['taxonomies:entry'];
                const arrayData = parseAllRecordsData(parsedData, payload);
                return { data: List(arrayData) };
            }
            return { data: List([]) };
        })
        .catch((error) => ({ error }));
}

我的测试:

describe('fetchAllRecordsData', () => {
    const mockedPayload = {
        link: 'apis/ok_link',
    };

    beforeAll(() => {
        jest.spyOn(LegalListRecordsApi,'parseAllRecordsData').mockReturnValue(['test']);
    });

    it('test', async () => {
        const test = await LegalListRecordsApi.fetchAllRecordsData(mockedPayload);
        expect(test).toEqual(1);
    });
});

这样调用时,parseAllRecordsData会调用实函数,并引发错误,因为模拟的Axios响应没有解析函数使用的某些值。我只对返回值感兴趣,不调用此函数。

2 个答案:

答案 0 :(得分:1)

jest.spyOn(LegalListRecordsApi,'parseAllRecordsData').mockReturnValue(['test']);模拟parseAllRecordsData模块导出

这对fetchAllRecordsData没有任何影响,因为它与parseAllRecordsData在同一模块中,并且正在直接调用

ES6模块supports cyclic dependencies,因此您可以将模块导入自身。

将模块导入自身并使用该模块调用parseAllRecordsData

import * as LegalListRecordsApi from './LegalListRecordsApi';  // import module into itself

export function fetchAllRecordsData(payload) {
  const url = `/apis/${payload.link.split('apis/')[1]}`;
  return axios.get(url)
    .then(({ data }) => {
      if (data && data._embedded) {
        const parsedData = data._embedded['taxonomies:entry'];
        const arrayData = LegalListRecordsApi.parseAllRecordsData(parsedData, payload);  // use the module
        return { data: List(arrayData) };
      }
      return { data: List([]) };
    })
    .catch((error) => ({ error }));
}

...,并且在模拟parseAllRecordsData的模块导出时,将模拟该调用。

答案 1 :(得分:0)

export function fetchAllRecordsData(payload, axiosInterface = axios) {
  return return axiosInterface.get(url)
   . then(({ data }) => {
      // your code
    })
   .catch((error) => ({ error }))
}

因此,您需要使用方法get创建模拟对象,方法get应该返回promise。