缓存修改包,例如decache
应该在这种情况下工作,如果require('settings.json')
之后重新评估decache('settings.json')
, i.e. Config.get()
叫做。
因为它是settings.json
模块对象被修改后,应该将其恢复。decache
应该直接影响应该取消缓存的包,即settings.json
. If Config.get()
不会被多次调用,./config'
并且导入它的每个模块也应该被取消缓存。这使得利用decache
在这种情况下是不合理的。
这里的问题是配置模块不适合测试。仅静态类是反模式。如果Config
没有像代码所示那样导出,这也是反模式,因为它提供了一个在模块导出时不能多次使用的抽象。
为了改善这种情况,配置模块应该以能够重新评估的方式进行重构require('settings.json')
在导入配置对象后使用配置对象的模块中:
export default function getConfig() {
return require('settings.json');
}
getConfig()
应始终按原样使用,不应分配const config = getConfig()
在使用它的模块的顶部,这将使其不可缓存。
目前恢复原始配置的一种方法是修改它,同时保留对现有对象的引用,例如:
afterEach(() => {
decache('./settings.json');
Object.assign(Config, require('./settings.json'));
});
可见。 Config.get 抽象没有任何帮助。
另一种方式进入转译的ES模块是直接对模块对象进行补丁。由于根据规范,模块对象应该是导出的只读反映。预计转译器(包括 TypeScript)会相应地处理模块。这取决于应用程序的构建方式,并且可能无法在任何环境中按预期工作。
import Config from './config';
console.log(Config.foo);
应该被转译为类似的东西
Object.defineProperty(exports, "__esModule", { value: true });
console.log(config_1.default.foo;);
这可能允许动态修改 ES 模块导出(CommonJS 模块默认导出不可能)并影响那些使用的模块部分Config
并重新评估(例如,在函数内部但不在顶级模块范围内):
afterEach(() => {
decache('./settings.json');
const configModule = require('./config'));
configModule.default = require('./settings.json');
});