首页 > 解决方案 > 为什么模拟 axios get 方法返回未定义?

问题描述

我编写了一个相当简单的异步方法,通过 HTTP 检索结果:

import axios from "axios";

const BASE_URI = "http://api.tvmaze.com";

export const getSearchShows = async (search: string) => {
  const uri = `${BASE_URI}/search/shows?q=${encodeURIComponent(search)}`;
  const response = await axios.get(uri);

  return response.data;
};

我想对它进行单元测试。所以我写了下面的 Jest 测试,它打算模拟 axios 并返回假结果,然后我可以断言:

import axios from "axios";

import fakeSearchShowsResponse from "../data/search-shows--q=test.json";

import { getSearchShows } from "./TvShows.http";

jest.mock("axios");

describe("TvShows.http", () => {
  describe("getSearchShows", () => {
    it("retrieves shows over http and correctly deserializes them", async () => {

      const mockAxiosGet = jest.spyOn(axios, "get");

      mockAxiosGet.mockImplementation(async () => fakeSearchShowsResponse);

      const shows = await getSearchShows("test");

      console.log(mockAxiosGet.mock.calls);

      expect(shows[0].id).toEqual(139);

    });
  });
});

我预计,由于调用jest.mock("axios"),axios get 方法将被替换为模拟的 Jest 方法。

此外,我预计由于调用mockAxiosGet.mockImplementation并传递了一个函数,对 axios get 方法的调用实际上会调用我的模拟函数,从而允许我用测试数据替换真实数据。

实际发生的是对 axios get 的调用返回undefined,导致我的测试断言失败。

然而,奇怪的是,Jest 间谍仍然记录该方法被调用——console.log 输出一个调用。

undefined那么,当我明确提供了一个返回值的模拟实现时,为什么这个所谓的模拟方法会返回呢?

还是我误解了 mockImplementation 的使用方式?

标签: javascriptreactjsunit-testingjestjsaxios

解决方案


因此,经过一些实验后,似乎该jest.mock("axios")呼叫正在干扰jest.spyOn(axios, "get");呼叫。

删除 jest.mock 调用后,它现在从 jest.spyOn 调用返回我的模拟值。

我认为这可能是因为 jest.mock 调用被提升了,而 jest.spyOn 调用没有。因此,被测模块脱离了悬挂的模拟,而不是未悬挂的模拟。


推荐阅读