如何编写Jest测试用例覆盖NestJS代码的可选链分支
NestJS Jest测试覆盖
query?.role_id可选链分支解决方案 问题背景
编写NestJS应用的Jest测试时,业务代码中query?.role_id的可选链分支未被代码覆盖率统计覆盖。相关代码如下:
业务代码
async getUsers(query: GetUsersQueryDto): Promise<UsersDto[]> { const findWhereOptions: FindOptionsWhere<Users> = { is_deleted: false }; if (query?.role_id) { findWhereOptions.role_id = query.role_id; } else { const adminRole = await this.rolesService.getRoleByName(Role.SUPER_ADMIN); findWhereOptions.role_id = Not(adminRole.id); } const list = await this.usersRepository.find({ where: findWhereOptions, relations: { role: true, facility: true }, }); return UsersService.convertToDto(list); }
现有测试用例
it("getUsers: should return users data", async () => { jest.spyOn(repository, "find").mockResolvedValue([validMockUser]); const result = await service.getUsers({ role_id: "1" }); expect(result).toEqual([validMockResponseUser]); });
解决方案
需要补充以下测试用例,覆盖query?.role_id的所有分支场景:
1. 测试query为undefined/null的场景(覆盖可选链触发的分支)
当传入的query为undefined或null时,query?.role_id会返回undefined,进入else分支:
it("getUsers: should exclude super admin users when query is undefined", async () => { const mockAdminRole = { id: "admin-id" }; jest.spyOn(rolesService, "getRoleByName").mockResolvedValue(mockAdminRole); jest.spyOn(repository, "find").mockResolvedValue([validMockNonAdminUser]); const result = await service.getUsers(undefined); expect(repository.find).toHaveBeenCalledWith(expect.objectContaining({ where: { is_deleted: false, role_id: Not(mockAdminRole.id) } })); expect(result).toEqual([validMockNonAdminResponseUser]); });
2. 测试query存在但role_id为假值的场景
当query存在但role_id为空字符串、null等假值时,同样进入else分支:
it("getUsers: should exclude super admin users when role_id is falsy", async () => { const mockAdminRole = { id: "admin-id" }; jest.spyOn(rolesService, "getRoleByName").mockResolvedValue(mockAdminRole); jest.spyOn(repository, "find").mockResolvedValue([validMockNonAdminUser]); const result = await service.getUsers({ role_id: "" }); expect(repository.find).toHaveBeenCalledWith(expect.objectContaining({ where: { is_deleted: false, role_id: Not(mockAdminRole.id) } })); expect(result).toEqual([validMockNonAdminResponseUser]); });
3. 保留原有测试(覆盖role_id为真值的分支)
原有测试已经覆盖了query?.role_id为真值的情况,可继续保留,确保分支覆盖完整。
说明
通过补充上述测试用例,能够覆盖query?.role_id的所有分支:
query为undefined/null时的可选链分支query存在但role_id为假值的分支query存在且role_id为真值的分支
同时需要确保测试中正确mockrolesService和usersRepository的依赖,保证测试的独立性和准确性。
内容的提问来源于stack exchange,提问作者Abhimanyu Patil
相关产品推荐
相关产品推荐

