#javascript #node.js #unit-testing #mocha.js #sinon
#javascript #node.js #модульное тестирование #mocha.js #sinon
Вопрос:
Я программист на Java, c # с более чем 10-летним опытом. Теперь мне нужно написать некоторый код на js, и я действительно чувствую себя Алисой в Стране чудес….
У меня есть myModule.js :
module.exports = function (logger) {
return {
read: function (param) {
......
logger.eror(....)
},
write: function (param) {
......
logger.info(....)
}
};
}
The logger.js (устаревший код, я не могу его изменить) выглядит аналогично:
module.exports = function(some_settings){
return {
info: function () {
......
},
error: function () {
......
}
};
}
Важная вещь: logger не включен в MyModule с помощью require («logger»), но введен в некотором «глобальном» index.js файл, который выглядит как:
var settings = require("../someSettings.js")();
var logger = require("../logger.js")(settings);
var myModule = require("../myModule .js")(logger);
Теперь я хочу написать UT для MyModule на mocha. Итак, я хочу издеваться над регистратором. И я лицом к стене.
Я попробовал proxyquire, но это не очень хорошее решение, потому что logger не включен в MyModule по require.
Я попробовал заглушку sinon и макет, например:
var logger = require("logger.js");
var loggerMock = sinon.mock(logger);
var myModule= require("myModule.js")(loggerMock);
Или:
var logger = require("logger.js");
var loggerStub = sinon.stub(logger, "info", function() {return ....});
var myModule= require("myModule.js")(loggerStub);
Но у меня все еще есть некоторые ошибки, такие как :
«Попытка обернуть ошибку неопределенного свойства в функцию»…
Пожалуйста, будь моим белым кроликом в этом мире свободного javascript…
Ответ №1:
Когда вы тестируете свой модуль, вы можете использовать поддельный объект для вашего объекта logger, т.Е.:
const logger = {info: noop, error: noop, debug:...};
function noop() {}
или мы создадим макет объекта с sinonjs
помощью, если вы предпочитаете создавать его программно и использовать шпионские функции.
Затем вы можете внедрить его, обернув определение вашего модуля в замыкание (как вы опубликовали):
# myModule.js:
module.exports = (dep1, dep2, ...) => {
// module definition
}
Или используйте rewire
package, чтобы «внедрить» зависимости, охватываемые модулем (это работает только для локальных переменных, и не нужно создавать замыкание в вашем модуле):
# myModuleTest
myModule = rewire('./myModule');
myModule.__set__('logger', { /* fake logger */ });