У нас есть приложение SPA с переменной общего объема var WIDGET . Каждый модуль добавляет себя к общему объекту WIDGET или создает WIDGET , если он не был создан.
При использовании нескольких платформ для модульных тестов общий WIDGET доступен, но переменная в требуемых файлах не указывает на него.
var WIDGET = WIDGET || {};
если я изменю эту строку кода на WIDGET = WIDGET || {} или если я удаляю все это вместе, то объекты будут работать так, как ожидается в модульном тесте
что нужно знать:
- мы НЕ используем nodejs в производстве, это только для тестирования
- код выполняется правильно в производстве
- тестовые рамки были мокко и шутка
Q1 что я могу сделать, чтобы частная переменная указывала на общий объект при модульном тестировании?
Q2, почему это происходит при тестировании, а не в DOM во время выполнения приложения?
test application creation:
TypeError: Cannot read property 'getInstance' of undefined
at new widget_application (widgetApplication.js:23:41)
at Object.getInstance (widgetApplication.js:33:16)
at Context.<anonymous> (test\testApp.js:16:39)
первый модуль, который добавляет себя в WIDGET объект
var _WIDGET_ = _WIDGET_ || {};
//adds itself to the _WIDGET_ to be shared
_WIDGET_.widgetLogger = (function(){
var INSTANCE;
var _config = {};
var _widgetLog = {};
function widget_logger(config){
if(config){_config = config;}
}
widget_logger.prototype.stageLog = stageLog;
// widget_logger.prototype.startUpLog = startUpLog;
// widget_logger.prototype.dataRefreshLog = dataRefreshLog;
// widget_logger.prototype.widgetNotReadyLog = widgetNotReadyLog;
// widget_logger.prototype.finalizeLog = finalizeLog;
// widget_logger.prototype.getLog = getLog;
return {
getInstance:function(c){
if(!INSTANCE){
INSTANCE = new widget_logger(c);
}
return INSTANCE;
}
};
function stageLog(data) {
console.log("widget logger called to stage log");
if(data){
_widgetLog = {};
_legacyLog = {};
_widgetLog.widgetProgramCode = _config.versionData.programCode;
_widgetLog.widgetVersion = _config.versionData.version;
_widgetLog.startTime = data.startTime || new Date();
console.log("widget logger staged this log ",_widgetLog);
}
}
})();
//export is only for testing - nodejs NOT used in production
var module = module || {};
module.exports = _WIDGET_;
следующий модуль, который добавляет себя и использует модуль логгера
var _WIDGET_ = _WIDGET_ || {};//remove this line of code and unit test run
var _API_ = _API_ || {};
_WIDGET_.smallApplication = (function(){
var INSTANCE;
var widgetLogger;
var _config = {
versionData:{
programCode:"smallApplication",
version:"1.0.2.0"
}
};
function widget_application(config){
console.log("make the instance ");
// var elem = document.getElementById('apprunning');
// elem.innerHTML += " smallApplication is online ";
if(config){_config = config;}
//expects to have a shared object already
//fails after this call because this module create a new _WIDGET_ variable
//this does not happen in production - all components are created
widgetLogger = _WIDGET_.widgetLogger.getInstance(_config);
}
widget_application.prototype.runApplication = runApplication;
return {
getInstance:function(c){
console.log("get instance was called");
if(!INSTANCE){
INSTANCE = new widget_application(c);
}
return INSTANCE;
}
};
//run some functions and hello world and all that happiness...
function runApplication(){
console.log("widget application runs - will call logger");
widgetLogger.stageLog(true);
}
})();
//export is only for testing - nodejs NOT used in production
var module = module || {};
module.exports = _WIDGET_;
Скрипт теста мокко
var assert = require('assert');
_WIDGET_ = {name: 'small application'};
describe('small application',function(){
//_WIDGET_ = {name: 'small application'};
//var _WIDGET_ {name: 'small application'};
//global._WIDGET_ {name: 'small application'};
it('test logger creation',function(){
_WIDGET_ = require('../widgetLogger');
console.log('_WIDGET_');
});
it('test application creation',function(){
var app = require('../widgetApplication');
_WIDGET_ = require('../widgetApplication');
});
});
от А2 до Q2 найдено в свободный код лагеря - требуются модули В браузере, когда мы объявляем переменную в сценарии, например:
var answer = 42;
Эта переменная ответа будет доступна во всех сценариях после сценария, который ее определил.
Это не относится к Node. Когда мы определяем переменную в одном модуле, другие модули в программе не будут иметь доступа к этой переменной. Так почему же переменные в Node магически ограничены?
Ответ прост. Перед компиляцией модуля Node упаковывает код модуля в функцию, которую мы можем проверить с помощью свойства wrapper модуля module.