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

时间:2019-09-06 05:55:19

标签: javascript reactjs unit-testing jestjs axios

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

import mod1
import mod2

def qux():
    while input():
        print(mod1.bar())
        print(mod2.baz())

if __name__=='__main__':
    qux()

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

<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>A</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>L...</td>
    </tr>
    <tr>
      <th>1</th>
      <td>b</td>
    </tr>
  </tbody>
</table>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>B</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>a</td>
    </tr>
    <tr>
      <th>1</th>
      <td>T...</td>
    </tr>
  </tbody>
</table>

我希望由于调用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; }; ,axios get方法将被模拟的Jest方法取代。

此外,我希望由于调用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); }); }); }); 并将其传递给函数,因此对axios get方法的调用实际上会调用我的模拟函数,从而使我可以用测试数据代替真实数据。

实际上发生的是,对axios get的调用返回了jest.mock("axios"),导致我的测试断言失败。

但是,奇怪的是,Jest间谍仍在注册该方法已被调用– console.log输出一个调用。

那么当我显式提供一个返回值的模拟实现时,为什么这个假定的模拟方法返回mockAxiosGet.mockImplementation

还是我误解了应如何使用模仿实现?

2 个答案:

答案 0 :(得分:0)

因此,经过一些试验,似乎jest.mock("axios")调用正在干扰jest.spyOn(axios, "get");调用。

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

我认为这可能是因为jest.mock调用被挂起,而jest.spyOn调用没有被挂起。因此,被测试的模块是从吊装的模拟装置上卸下的,而不是从非吊装的模拟装置上卸下的。

答案 1 :(得分:0)

jest.mock('axios')将模拟整个模块,并用存根替换所有内容。因此,它不一定与悬挂jest.mock()的事实有关,而只是确保在导入之前模拟依赖项。只是存根返回undefined

同时,您可以

import axios from 'axios';

jest.mock('axios');

console.log(axios); // mocked

describe('suite', () => {
  it('test', () => {
    axios.get.mockResolvedValue('{"test": "test"}');
    // --------------------------^
    // you class would get this when calling axios.get()

    // you could also do some assertion with the mock function
    expect(axios.get).toHaveBeenCalledTimes(1);
    expect(axios.get).toHaveBeenCallWith('http://some-url');
  });
});