NestJS项目中members.service.ts无法实现完整测试覆盖率如何解决
问题根因
你当前的测试逻辑存在核心错误:直接将整个MembersService替换为自定义的Mock类,所有测试用例执行的都是Mock类的方法,完全没有运行真实members.service.ts中的业务代码,这就是覆盖率极低的根本原因。
我们的测试思路应该是:保留真实的MembersService实例,只Mock它依赖的外部资源(这里就是mongoose注入的financeMembersModel模型)。
修正后的测试代码
import { Test, TestingModule } from '@nestjs/testing'; import { MembersService } from './members.service'; import { memberData } from './mockMembersData'; import { HttpException } from '@nestjs/common'; // 只Mock mongoose返回的链式查询方法 const mockFind = jest.fn().mockReturnThis(); const mockSort = jest.fn().mockReturnThis(); const mockLimit = jest.fn(); describe('MembersService', () => { let membersService: MembersService; beforeAll(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [ MembersService, { // 替换注入的mongoose模型为Mock对象 provide: 'finance_members', useValue: { find: mockFind, sort: mockSort, limit: mockLimit } } ], }).compile(); membersService = module.get<MembersService>(MembersService); }); // 每个用例执行前清空之前的mock调用记录 beforeEach(() => { jest.clearAllMocks(); }) it('service 实例正常初始化', () => { expect(membersService).toBeDefined(); }); it('查询会员详情成功,返回对应数据', async () => { // 模拟limit返回正常的会员数组 mockLimit.mockResolvedValue([memberData]); const result = await membersService.getMemberDetails('test_guid_123'); // 验证调用链路参数是否正确 expect(mockFind).toHaveBeenCalledWith({ guid: 'test_guid_123' }); expect(mockSort).toHaveBeenCalledWith({ _id: -1 }); expect(mockLimit).toHaveBeenCalledWith(1); expect(result).toEqual(memberData); }); it('查询不到对应会员,返回undefined', async () => { // 模拟limit返回空数组 mockLimit.mockResolvedValue([]); const result = await membersService.getMemberDetails('not_exist_guid'); expect(result).toBeUndefined(); }); it('查询出现异常,抛出对应HttpException', async () => { // 模拟查询抛出错误 const mockError = { response: { status: 400 }, message: '数据库查询错误' }; mockLimit.mockRejectedValue(mockError); await expect(membersService.getMemberDetails('error_guid')).rejects.toThrow(HttpException); await expect(membersService.getMemberDetails('error_guid')).rejects.toMatchObject({ status: 400, response: { ...mockError } }); }); });
覆盖率提升说明
上述测试用例覆盖了getMemberDetails方法的所有分支:
- try块的正常查询、返回空值场景
- catch块的异常抛出场景
运行测试后你的service文件覆盖率可以达到100%,完全满足80%的要求。
内容的提问来源于stack exchange,提问作者user562451
相关产品推荐
相关产品推荐

