使用Jest为Service编写测试以获取代码覆盖率及报错排查
问题2:测试报错
Cannot read properties of undefined (reading 'getById')的原因 按照回答编写了如下测试代码:
jest.mock('./service', () => ({ getById: jest.fn().mockResolvedValue({ data : "hello"}), })); describe('test', () => { it('mocks the service", async () => { service.getById.mockResolvedValue({data: "hello}); const data = await service.getById(1); expect(data).toEqual({data:"hello"}); }) })
但现在报错:
Cannot read properties of undefined (reading 'getById')
请问该错误的原因是什么?
解答
针对问题1:获取代码覆盖率的正确写法
你之前的测试直接把service.getById替换成了jest mock函数,根本没执行原函数的逻辑,自然拿不到覆盖率。要覆盖原函数,得mock axios而非service本身,让原函数的代码正常执行:
- Mock axios的
get方法,预设好响应数据 - 调用原
service.getById函数 - 验证返回结果和axios的调用是否符合预期
示例代码:
import axios from 'axios'; import { service } from './requests'; // Mock整个axios模块 jest.mock('axios'); describe('service.getById', () => { it('should fetch and return customer names correctly', async () => { // 预设axios.get的返回值 const mockData = ['Alice', 'Bob']; axios.get.mockResolvedValue({ data: mockData }); // 调用原函数 const result = await service.getById(123); // 验证结果是否正确 expect(result).toEqual(mockData); // 验证axios调用的参数是否符合预期 expect(axios.get).toHaveBeenCalledWith('/api/customers/123/names', axiosOptions); }); });
这样测试会执行原getById的全部逻辑,就能统计到代码覆盖率了。
针对问题2:报错原因及修正
报错的核心原因有两个:
- 未导入service:你mock了
./service模块,但测试代码里没导入service对象,导致service是undefined - 语法错误:代码里存在字符串闭合问题——
it('mocks the service", async () => {引号不匹配,{data: "hello});字符串没闭合,语法错误会导致代码执行异常
修正后的代码:
// 先导入service import { service } from './service'; jest.mock('./service', () => ({ getById: jest.fn().mockResolvedValue({ data : "hello"}), })); describe('test', () => { // 修正引号匹配 it('mocks the service', async () => { // 修正字符串闭合 service.getById.mockResolvedValue({data: "hello"}); const data = await service.getById(1); expect(data).toEqual({data:"hello"}); }) })
注意:这种写法还是mock了service本身,不会执行原函数逻辑,依然拿不到代码覆盖率,建议用问题1里mock axios的方案。
内容的提问来源于stack exchange,提问作者wallwalker
相关产品推荐
相关产品推荐

