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

时间:2018-07-11 00:01:55

标签: reactjs typescript axios jestjs

我在课堂上有以下方法:

import axios from 'axios'

public async getData() {
   const resp = await axios.get(Endpoints.DATA.URL)
   return resp.data
}

然后我正在尝试设置一个Jest测试来做到这一点:

jest.mock('axios')

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

问题在于,因为我没有嘲笑返回值,所以它为resp.data给出了错误,因为我在datanull对象上调用undefined 。我花了至少2个小时的时间尝试各种方法来使此工作正常进行,但是我找不到能够模拟axios.get并带有一些返回值的方法。

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

此外,如果您知道除Jest之外其他可用于TypeScript轻松完成此工作的React良好测试库,请随时共享。

7 个答案:

答案 0 :(得分:4)

在文件开头:

import axios from 'axios';
jest.mock('axios');
const mockedAxios = axios as jest.Mocked<typeof axios>;

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

mockedAxios.get.mockRejectedValue('Network error: Something went wrong');
mockedAxios.get.mockResolvedValue({ data: {} });

答案 1 :(得分:3)

  

但是我不能调用mockResolvedValue,因为TypeScript中的axios.get上不存在该方法

您可以使用断言:

(axios.get as any).mockResolvedValue(resp)

答案 2 :(得分:2)

我使用sinonnpm install sinon @types/sinon --save-dev找到了一个很好的解决方案。

然后测试代码变为:

let component: Component
let axiosStub: SinonStub

beforeAll(() => {
    component = new Component({})
    axiosStub = sinon.stub(axios, 'get')
})

afterAll(() => {
    axiosStub.restore()
})

it('make api call to get data', async () => {
    // set up behavior
    axiosStub.withArgs(Endpoints.DATA.URL).returns({data: []})

    // method under test
    const res = await component.getData()

    // assertions
    expect(res).toEqual([])
})

答案 3 :(得分:2)

如果要将jest.mock"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)
})

答案 4 :(得分:2)

这是我个人经常使用的。

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

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

答案 5 :(得分:1)

我一直遇到is not a function个问题。如果接受的答案对您不起作用,请尝试以大写字母A即axios导入。 Axios

import Axios from 'axios';
jest.mock('Axios');
const mockedAxios = Axios as jest.Mocked<typeof Axios>;

答案 6 :(得分:0)

另一种选择是使用 jest.spyOn

import axios from "axios";

jest.spyOn(axios, "get").mockImplementation(() => Promise.resolve({data: []}));

这也为您提供了一个可以测试的模拟方法的好处,例如:

import axios from "axios";

// ...

const mockedGet = jest
  .spyOn(axios, "get")
  .mockImplementation(() => Promise.resolve({data: []}));

// ...

expect(mockedGet).toBeCalledWith('https://example.api?q=abc&k=123');