You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jest中mock被测服务依赖的storageConnectionString常量?

问题描述

我正在测试名为connect-key.js的文件,该文件依赖keyvault-emulator模块。相关文件代码如下:

文件1:connect-key.js

// connect-key.js file
const { save, retrieve, init  } = require('./keyvault-emulator')
....
....
....
// SOME TESTS

文件2:keyvault-emulator.js

// The keyvault-emulator.js file
const { storageConnectionString } = require('../config')

配置文件:config.js

// config.js file
module.exports = {
  storageConnectionString: process.env.STORAGE_CONNECTION_STRING || process.env.Storage,
  keyVaultName: process.env.KEY_VAULT
}

我想在测试文件connect-key.spec.js中mock storageConnectionString的值,设想的实现方式如下:

// The connect-key.spec.js file
const keyvault_emulator = require('../keyvault-emulator');
const spy = jest.spyOn(keyvault_emulator, 'storageConnectionString');
spy.mockReturnValue('');

请问这种方式是否正确?实现该需求的最优方法是什么?


解答

你的实现方式是否正确?

不正确。因为keyvault-emulator.js是解构导入了config.js里的storageConnectionString,这个值在模块加载时就被存入了keyvault-emulator的局部作用域,并不会成为keyvault_emulator导出对象的属性。你用jest.spyOn去监听不存在的属性,自然会失败。

最优实现方法

方法1:直接mock整个config模块(推荐)

用Jest的jest.mock直接替换config.js模块,指定你需要的mock值,这种方式最直接且不需要改动业务代码:

// connect-key.spec.js
// 先mock配置模块,再导入被测试代码
jest.mock('../config', () => ({
  storageConnectionString: '你的mock连接字符串',
  keyVaultName: '任意mock值或保留原值'
}));

// 导入被测试模块
const { save, retrieve, init } = require('../connect-key');

// 编写测试用例
test('测试save方法', () => {
  // ...你的测试逻辑
});

模块加载时会直接使用你定义的mock配置,无需考虑加载顺序问题。

方法2:mock环境变量

因为config.js里的storageConnectionString是从环境变量读取的,你可以在测试前直接设置环境变量:

// connect-key.spec.js
beforeAll(() => {
  // 保存原始环境变量,避免影响其他测试
  this.originalStorageEnv = process.env.STORAGE_CONNECTION_STRING;
  process.env.STORAGE_CONNECTION_STRING = '你的mock连接字符串';
});

afterAll(() => {
  // 测试结束后恢复原始环境变量
  process.env.STORAGE_CONNECTION_STRING = this.originalStorageEnv;
});

// 必须在设置环境变量之后再导入模块
const { save, retrieve, init } = require('../connect-key');

// 测试用例
test('测试retrieve方法', () => {
  // ...测试逻辑
});

这种方式适合依赖环境变量的场景,但要严格注意模块导入顺序——必须先设置环境变量再导入被测试模块,否则原始值已经被读取了。

方法3:修改业务代码的导入方式(不推荐)

如果允许改动keyvault-emulator.js,可以把解构导入改成导入整个config对象,这样就能mock其属性:

// 修改后的keyvault-emulator.js
const config = require('../config');
// 使用时改为config.storageConnectionString

然后在测试中:

const config = require('../config');
jest.spyOn(config, 'storageConnectionString', 'get').mockReturnValue('你的mock值');

这种方式需要改动业务代码,除非必要否则不推荐。

内容的提问来源于stack exchange,提问作者mcool

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 11:10:42