我在课堂上有以下方法:
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
给出了错误,因为我在data
或null
对象上调用undefined
。我花了至少2个小时的时间尝试各种方法来使此工作正常进行,但是我找不到能够模拟axios.get
并带有一些返回值的方法。
Jest的文档使用JavaScript,因此他们给出了示例axios.get.mockResolvedValue(resp)
,但是我不能调用mockResolvedValue
,因为TypeScript中的axios.get
上不存在该方法。
此外,如果您知道除Jest之外其他可用于TypeScript轻松完成此工作的React良好测试库,请随时共享。
答案 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)
我使用sinon
库npm 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');