Пакеты с кэшированием, такие как decache
, должны работать в этом случае, если require('settings.json')
переоценивается после decache('settings.json')
, то есть вызывается Config.get()
.
Поскольку это settings.json
объект модуля, который являетсямодифицированный, он должен быть восстановлен.decache
должен напрямую влиять на пакет, который должен быть удален из кэша, то есть settings.json
.Если 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');
});