React项目中如何测试CDN引入的Tesseract OCR包构造函数调用?
解决Tesseract.js测试时全局对象找不到的问题
我之前也碰到过类似的坑,核心原因是测试环境(比如Jest这类测试框架)不会自动加载你index.html里的CDN脚本,所以window/global上根本没有Tesseract这个对象,自然会抛出Cannot read property 'TesseractWorker' of undefined的错误。下面给你几个实用的解决方案:
方案一:直接在测试文件中模拟全局Tesseract对象
因为测试只需要验证逻辑,不需要真实调用OCR功能,直接模拟Tesseract的API就够了。在你的测试文件顶部添加这段代码:
// 模拟全局的Tesseract对象及Worker window.Tesseract = { TesseractWorker: jest.fn(() => ({ // 模拟recognize方法,返回你需要的测试数据 recognize: jest.fn().mockResolvedValue({ text: `An updated look at all the ways that autonomous vehicles will change our lives in profound ways.` }), // 如果你的代码用到了progress方法,也一起模拟 progress: jest.fn().mockResolvedValue({}) })) };
然后修改你的测试用例,修正原来的worker调用错误(你原来的写法是把worker当成函数调用了,实际应该是实例的方法):
import getDetails from '../getDetails'; describe('getDetails() function', () => { const file = { name: 'image.png' }; const response = { data: {} }; it('should return ticket details', async () => { // 调用getDetails并断言结果 const result = await getDetails(file); // 根据你的业务逻辑添加断言,比如: expect(result).toContain('autonomous vehicles'); // 也可以验证Worker的方法是否被调用 const workerInstance = window.Tesseract.TesseractWorker.mock.results[0].value; expect(workerInstance.recognize).toHaveBeenCalledWith(file); }); });
方案二:全局配置测试环境的mock(推荐)
如果多个测试文件都需要用到Tesseract的mock,可以把这段模拟代码放到测试的全局配置文件里,避免重复编写:
- 在你的项目里创建
src/setupTests.js文件,添加模拟代码:
window.Tesseract = { TesseractWorker: jest.fn(() => ({ recognize: jest.fn().mockResolvedValue({ text: '测试文本' }), progress: jest.fn() })) };
- 修改
jest.config.js(如果没有就新建),指定全局setup文件:
module.exports = { setupFiles: ['./src/setupTests.js'] };
这样所有测试文件运行时都会自动加载这个mock,不用每个文件都写一遍。
为什么不推荐在测试环境加载真实CDN?
虽然可以用jsdom手动加载CDN脚本,但这样会让测试变慢,而且测试依赖外部资源,容易不稳定。测试的核心是验证你的业务逻辑,而不是Tesseract本身的功能,所以模拟是更优的选择。
内容的提问来源于stack exchange,提问作者ebzeal
相关产品推荐
相关产品推荐

