如何用Jest测试导入构造函数类库的模块(pdfmake场景)
解决Jest测试pdfmake时的TypeError: PdfPrinter is not a constructor问题
这个报错的核心原因是你对pdfmake的mock方式不对——pdfmake导出的是一个构造函数(也就是你代码里的PdfPrinter),但你当前的mock返回的是一个普通对象,所以当执行new PdfPrinter()时,Jest会认为你在尝试实例化一个非构造函数,自然就报错了。
接下来我给你调整一下测试代码,同时覆盖你pdf.js里的两个导出函数:
首先,正确mock pdfmake:
const PdfPrinter = require("pdfmake"); const { intiateDocCreation, finishDocCreation } = require("./pdf"); // 替换成你的pdf.js实际路径 const fonts = require("./../shared/fonts"); // 替换成字体文件的正确路径 // 模拟pdfDoc的pipe和end方法,适配finishDocCreation的调用 const mockPdfDoc = { pipe: jest.fn(), end: jest.fn() }; // 正确模拟pdfmake的构造函数导出逻辑 jest.mock("pdfmake", () => { // 返回一个模拟的构造函数,让new PdfPrinter()能正常生成实例 return jest.fn().mockImplementation(() => ({ // 给实例添加createPdfKitDocument方法,返回我们预定义的mockPdfDoc createPdfKitDocument: jest.fn().mockReturnValue(mockPdfDoc) })); }); describe("PDF生成模块测试", () => { beforeEach(() => { // 每次测试前重置所有mock的调用记录,避免用例间干扰 jest.clearAllMocks(); }); test("intiateDocCreation应该正确调用printer的createPdfKitDocument方法", () => { const testDocDefinition = { content: "测试PDF内容" }; intiateDocCreation(testDocDefinition); // 验证PdfPrinter构造函数被正确实例化 expect(PdfPrinter).toHaveBeenCalledTimes(1); expect(PdfPrinter).toHaveBeenCalledWith(fonts); // 验证createPdfKitDocument被传入正确参数调用 const mockPrinterInstance = PdfPrinter.mock.instances[0]; expect(mockPrinterInstance.createPdfKitDocument).toHaveBeenCalledTimes(1); expect(mockPrinterInstance.createPdfKitDocument).toHaveBeenCalledWith(testDocDefinition); }); test("finishDocCreation应该正确调用pdfDoc的pipe和end方法", () => { const mockPdfStream = {}; // 模拟一个输出流对象 finishDocCreation(mockPdfDoc, mockPdfStream); expect(mockPdfDoc.pipe).toHaveBeenCalledTimes(1); expect(mockPdfDoc.pipe).toHaveBeenCalledWith(mockPdfStream); expect(mockPdfDoc.end).toHaveBeenCalledTimes(1); }); });
关键调整点说明:
- 将mock返回值改成了jest模拟函数(构造函数),让
new PdfPrinter()能正常创建实例 - 给模拟的构造函数实例添加了
createPdfKitDocument方法,返回包含pipe和end的模拟文档对象,适配finishDocCreation的调用逻辑 - 测试中不仅验证方法调用次数,还验证了构造函数的传入参数、
createPdfKitDocument的参数,让测试覆盖更严谨 - 用
beforeEach重置mock调用记录,避免不同测试用例之间的状态污染
内容的提问来源于stack exchange,提问作者Zahra Ali
相关产品推荐
相关产品推荐

