为什么模拟的 axios get 方法返回未定义?

Jon*_*han 4 javascript unit-testing reactjs jestjs axios

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

\n\n
import axios from "axios";\n\nconst BASE_URI = "http://api.tvmaze.com";\n\nexport const getSearchShows = async (search: string) => {\n  const uri = `${BASE_URI}/search/shows?q=${encodeURIComponent(search)}`;\n  const response = await axios.get(uri);\n\n  return response.data;\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n

我想对其进行单元测试。因此,我编写了以下 Jest 测试,该测试旨在模拟 axios 并返回假结果,然后我可以对其进行断言:

\n\n
import axios from "axios";\n\nimport fakeSearchShowsResponse from "../data/search-shows--q=test.json";\n\nimport { getSearchShows } from "./TvShows.http";\n\njest.mock("axios");\n\ndescribe("TvShows.http", () => {\n  describe("getSearchShows", () => {\n    it("retrieves shows over http and correctly deserializes them", async () => {\n\n      const mockAxiosGet = jest.spyOn(axios, "get");\n\n      mockAxiosGet.mockImplementation(async () => fakeSearchShowsResponse);\n\n      const shows = await getSearchShows("test");\n\n      console.log(mockAxiosGet.mock.calls);\n\n      expect(shows[0].id).toEqual(139);\n\n    });\n  });\n});\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

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

\n\n

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

\n\n

然而,奇怪的是,Jest 间谍仍然注册该方法名为 \xe2\x80\x93,console.log 输出单个调用。

\n\n

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

\n\n

或者我是否误解了mockImplementation的用途?

\n

Jon*_*han 11

所以经过一番实验,看来是jest.mock("axios")通话干扰了通话jest.spyOn(axios, "get");

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

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