无法获得笑话+打字稿+ Axios测试

Ste*_*kov 8 typescript reactjs jestjs axios

我在课堂上有以下方法:

import axios from 'axios'

public async getData() {
   const resp = await axios.get(Endpoints.DATA.URL)
   return resp.data
}
Run Code Online (Sandbox Code Playgroud)

然后,我试图建立一个Jest测试来做到这一点:

jest.mock('axios')

it('make api call to get data', () => {
   component.getData()
   expect(axios.get).toHaveBeenCalledWith(Endpoints.DATA.URL)
})
Run Code Online (Sandbox Code Playgroud)

问题是,因为我不是嘲笑的返回值,那么它给出了一个错误resp.data,因为我打电话datanullundefined对象。我花了至少2个小时的时间尝试各种方法来使此工作正常进行,但是我找不到能够模拟axios.get一些返回值的方法。

Jest的文档使用JavaScript,因此他们给出了这个示例,axios.get.mockResolvedValue(resp)但我不能调用,mockResolvedValue因为axios.getTypeScript 中不存在该方法。

另外,如果您知道除Jest之外的React的其他优秀测试库,这些库很容易为TypeScript做到这一点,请随时共享。

小智 14

在文件开头:

import axios from 'axios';
jest.mock('axios');
const mockedAxios = axios as jest.Mocked<typeof axios>;
Run Code Online (Sandbox Code Playgroud)

现在您可以像平常一样使用它了:

mockedAxios.get.mockRejectedValue('Network error: Something went wrong');
mockedAxios.get.mockResolvedValue({ data: {} });
Run Code Online (Sandbox Code Playgroud)

  • 我做了完全相同的事情,但是打字稿将这个错误归咎于我的 { data: null } :`error TS2345: Argument of type '{ data: null; }' 不能分配给类型为 '(&lt;T = any&gt;(url: string, config?: AxiosRequestConfig | undefined) =&gt; AxiosPromise&lt;T&gt;) | 的参数 PromiseLike&lt;(&lt;T = any&gt;(url: string, config?: AxiosRequestConfig | undefined) =&gt; AxiosPromise&lt;T&gt;)&gt;'.` 不知道为什么它不起作用...... (4认同)

小智 13

如果你想使用jest.mockwith"no-any"试试这个:

import axios, { AxiosStatic } from 'axios'

interface AxiosMock extends AxiosStatic {
  mockResolvedValue: Function
  mockRejectedValue: Function
}

jest.mock('axios')
const mockAxios = axios as AxiosMock

it('make api call to get data', () => {
   // call this first
   mockAxios.mockResolvedValue(yourValue)

   component.getData()
   expect(mockAxios.get).toHaveBeenCalledWith(Endpoints.DATA.URL)
})
Run Code Online (Sandbox Code Playgroud)

  • 这有效,不需要另一个库,应该被接受的答案 (2认同)

Rui*_*ues 11

对于 Jest,24.9.0这里是如何正确键入axios和 Jest 属性的工作原理。

我们希望类型化模拟是模拟对象类型包含模拟对象类型和 Jest 模拟类型的并集。据我所知,目前的答案都不能实现这一点。

jest.MockedFunction

jest.MockedClass

import axios from 'axios';
jest.mock('axios');

const mockedAxios = axios as jest.MockedFunction<typeof axios>;

mockedAxios.mockResolvedValue({ status: 200, data: 'mockResponse' });

// Or:
(mockedAxios.get as jest.MockedFunction<typeof mockedAxios.get>).mockResolvedValue('mockResponse');
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,您可以手动转换您需要的内容,或者您​​需要一些东西来遍历所有 axios 属性/方法来键入所有内容。

为此(深度模拟类型),您可以使用Jest 中引入的jest.mocked()27.4.0

import axios from 'axios';
jest.mock('axios');

const mockedAxios = jest.mocked(axios, true); 

mockedAxios.mockImplementation() // correctly typed
mockedAxios.get.mockImplementation() // also correctly typed
Run Code Online (Sandbox Code Playgroud)


RM *_*Vos 8

这是我个人经常使用的。

import axios from 'axios';
jest.mock('axios')

it('...', () => {
  (axios.get as jest.Mock).mockImplementationOnce(() => Promise.resolve({}));
  // test here
  expect(axios.get).toHaveBeenCalled()
}
Run Code Online (Sandbox Code Playgroud)


Ren*_*use 7

我不断遇到is not a function问题。如果接受的答案不适合您,请尝试axios使用大写 A ie 导入。Axios

import Axios from 'axios';
jest.mock('Axios');
const mockedAxios = Axios as jest.Mocked<typeof Axios>;
Run Code Online (Sandbox Code Playgroud)