Cypress依赖模块Stub失效,运行时报pg-native模块未找到错误如何解决
问题原因
你遇到的编译报错和Stub逻辑本身无关,是Cypress的运行机制导致的:
Cypress测试默认在浏览器环境执行,你在测试代码顶层直接require('./foo')时,Cypress内置的Webpack会先编译加载foo.js的所有依赖,而pg-db-pool依赖的pg是仅Node.js服务端可用的数据库模块,浏览器环境不存在pg-native依赖,因此在代码加载阶段就会编译失败,还轮不到后续Stub逻辑执行。
解决方案(无需修改原始foo.js)
方案1:配置Webpack别名Mock服务端依赖
通过修改Cypress配置,让Webpack加载pg-db-pool时自动替换为你写的空Mock文件,跳过真实pg模块的加载:
- 新建
cypress/support/mock-pg.js,内容如下:
module.exports = {}
- 修改
cypress.config.js(Cypress 10+版本),配置Webpack别名:
const { defineConfig } = require('cypress') const path = require('path') const webpackPreprocessor = require('@cypress/webpack-preprocessor') module.exports = defineConfig({ e2e: { setupNodeEvents(on, config) { on('file:preprocessor', webpackPreprocessor({ webpackOptions: { resolve: { alias: { // 替换pg-db-pool依赖为Mock文件 './pg-db-pool': path.resolve(__dirname, 'cypress/support/mock-pg.js'), // 如果有其他pg相关依赖也可以直接Mock整个pg模块 'pg': path.resolve(__dirname, 'cypress/support/mock-pg.js') } } } })) return config } } })
- 修正你原有测试代码的断言错误(数字和字符串类型不匹配):
const foo = require('./foo') describe('Testing', () => { beforeEach(() => { cy.stub(foo, 'allrecords').returns(10) }) it('crud test - list', async () => { const list = foo.allrecords() // 去掉10的引号,匹配数字类型 expect(list).to.equal(10) }) })
方案2:使用Cypress Task在Node环境运行测试逻辑
如果不想修改Webpack配置,可以把测试逻辑放到Cypress的Node层Task中执行,直接避开浏览器环境的编译限制:
- 修改
cypress.config.js注册测试Task:
const { defineConfig } = require('cypress') const sinon = require('sinon') module.exports = defineConfig({ e2e: { setupNodeEvents(on, config) { on('task', { testAllRecords() { // Node环境直接加载foo.js,无浏览器编译限制 const foo = require('./foo') const stub = sinon.stub(foo, 'allrecords').returns(10) const result = foo.allrecords() stub.restore() return result } }) return config } } })
- 测试文件改为调用Task获取结果:
describe('Testing', () => { it('crud test - list', async () => { cy.task('testAllRecords').then(list => { expect(list).to.equal(10) }) }) })
内容的提问来源于stack exchange,提问作者Vinoth Karthick
相关产品推荐
相关产品推荐

