Jasmine编写Logger服务单元测试运行正常无代码覆盖率分数求助
问题根因
你当前的测试直接对Logger类自身的公开方法做了打桩(stub),实际运行测试时调用的是你伪造的stub方法,源码里的真实实现逻辑完全没有被执行,所以覆盖率工具无法统计到执行记录,自然不会返回有效覆盖率分数。
解决方案
我们需要Mock的是Logger内部依赖的Category实例,而非要测试的Logger本身,验证Logger的各个方法正确代理调用了内部Category实例的对应方法即可,同时覆盖error、fatal方法的两个分支(传Error/不传Error)拉满分支覆盖率。
调整后的单元测试代码(以Jest为例)
import { Logger } from "./logging.service"; import { Category } from 'typescript-logging'; // 全局mock Category类 jest.mock('typescript-logging', () => { const mockCategoryInstance = { trace: jest.fn(), debug: jest.fn(), info: jest.fn(), warn: jest.fn(), error: jest.fn(), fatal: jest.fn() }; return { Category: jest.fn(() => mockCategoryInstance) }; }); describe("Logger", () => { let logger: Logger; let mockCategoryInstance: jest.Mocked<Category>; beforeEach(() => { // 重置所有mock调用记录 jest.clearAllMocks(); logger = new Logger(); // 获取内部初始化的mock Category实例 mockCategoryInstance = (Category as jest.Mock).mock.results[0].value; }); it("调用trace方法时正确代理到内部Category实例的trace方法", () => { const testMsg = '测试trace信息'; logger.trace(testMsg); expect(mockCategoryInstance.trace).toHaveBeenCalledWith(testMsg); }); it("调用debug方法时正确代理到内部Category实例的debug方法", () => { const testMsg = '测试debug信息'; logger.debug(testMsg); expect(mockCategoryInstance.debug).toHaveBeenCalledWith(testMsg); }); it("调用info方法时正确代理到内部Category实例的info方法", () => { const testMsg = '测试info信息'; logger.info(testMsg); expect(mockCategoryInstance.info).toHaveBeenCalledWith(testMsg); }); it("调用warn方法时正确代理到内部Category实例的warn方法", () => { const testMsg = '测试warn信息'; logger.warn(testMsg); expect(mockCategoryInstance.warn).toHaveBeenCalledWith(testMsg); }); it("调用error方法且不传Error参数时,正确代理调用", () => { const testMsg = '测试error信息'; logger.error(testMsg); expect(mockCategoryInstance.error).toHaveBeenCalledWith(testMsg, null); }); it("调用error方法且传入Error参数时,正确代理调用", () => { const testMsg = '测试error信息'; const testError = new Error('测试错误'); logger.error(testMsg, testError); expect(mockCategoryInstance.error).toHaveBeenCalledWith(testMsg, testError); }); it("调用fatal方法且不传Error参数时,正确代理调用", () => { const testMsg = '测试fatal信息'; logger.fatal(testMsg); expect(mockCategoryInstance.fatal).toHaveBeenCalledWith(testMsg, null); }); it("调用fatal方法且传入Error参数时,正确代理调用", () => { const testMsg = '测试fatal信息'; const testError = new Error('测试致命错误'); logger.fatal(testMsg, testError); expect(mockCategoryInstance.fatal).toHaveBeenCalledWith(testMsg, testError); }); });
如果使用Vitest作为测试框架,将上述代码中的jest替换为vi即可,逻辑完全一致。
额外检查项
如果调整测试后仍然没有覆盖率输出,检查你的覆盖率工具配置:
- Jest场景:检查
jest.config.js中的collectCoverageFrom配置是否包含了你的logging.service.ts文件路径,排除了测试文件、声明文件等不需要统计的内容 - 确保运行测试时开启了覆盖率参数,比如Jest需要加
--coverage参数运行
内容的提问来源于stack exchange,提问作者HEMANT KUMAR
相关产品推荐
相关产品推荐

