Издевательство над издевательством os.type() не работает
Я пытаюсь провести модульное тестирование моего модуля, который зависит от базовой ОС.
Я пытаюсь использовать mockery для mock os.type(), чтобы вернуть Linux/Windows_NT на основе различных тестовых приспособлений.
Я использую мокко в качестве основы для юнит-теста.
У меня есть раздел описания, в котором описываются функциональные возможности модуля A моего модуля, в котором есть 2 блока описания: один для Windows и один для Linux.
Настройка: var reload = require("require-reload")(require); var module_we_test = reload('...');
var linuxOsMock = {
type: function () {
return "Linux";
}
};
var windowsOsMock = {
type: function () {
return "Windows_NT";
}
};
describe('#the_module_we_test', function() {
before(function() {
mockery.enable({
warnOnReplace: false
});
});
after(function() {
mockery.disable();
});
describe('#windows', function() {
before(function() {
mockery.registerMock('os', windowsOsMock);
module_we_test = reload('...');
});
describe('#functionality A', function() {
it('...', function() {
/* tests functionality A which is OS dependnet */
module_we_test.functionalityA();
});
});
describe('#linux & darwin', function() {
before(function() {
mockery.registerMock('os', linuxOsMock);
module_we_test = reload('...');
});
describe('#functionality A', function() {
it('...', function() {
/* tests functionality A which is OS dependnet */
module_we_test.functionalityA();
});
});
});
});
Причина, по которой мне требуется модуль, который я тестирую перед каждым зависимым от ОС тестовым приспособлением, заключается в том, что модуль использует модуль ОС один раз в глобальной области видимости для определения некоторых значений переменных, например:
var os = require('os');
var osType = os.type();
/* decide variable values based on os.type() return value */
так что я думаю, что если мне это не понадобится снова, перед каждым прибором вместо моего макета будет загружен изначально загруженный модуль ОС.
Теперь проблема в том, что он просто не заменяет модуль ОС в модуле, и я понятия не имею, почему.
1 ответ
Это происходит потому, что сверху вы делаете var module_we_test = require('...');
, Это загрузит оригинальный модуль и сохранит его в кеше. Таким образом, даже если вы будете издеваться над ним, используя каждый раз, когда вам это нужно, вы вернете кешированный оригинальный модуль. Вы должны использовать насмешку сначала, чтобы смоделировать модуль, а затем reload
тестируемый модуль. Перезагруженный модуль теперь извлечет смоделированный модуль. Вы можете сделать это с помощью модуля [require-reload][1].
Рабочий пример
describe('#the_module_we_test', function() {
before(function() {
mockery.enable({
warnOnReplace: false
});
});
after(function() {
mockery.disable();
});
describe('#windows', function() {
var module_we_test;
before(function() {
mockery.registerMock("os", windowsOsMock);
module_we_test = reload("...");
});
after(function(){
mockery.deregisterMock(windowsOsMock);
});
it("#functionality A", function() {
/* tests functionality A which is OS dependnet */
assert.equal(module_we_test.type(), "Windows_NT");
});
});
describe('#linux', function() {
var module_we_test;
before(function() {
mockery.registerMock("os", linuxOsMock);
module_we_test = reload("...");
});
after(function(){
mockery.deregisterMock(linuxOsMock);
});
it("#functionality A", function() {
/* tests functionality A which is OS dependnet */
assert.equal(module_we_test.type(), "Linux");
});
});
});
Обновить
После более тщательного прочтения документации mockery
Похоже, что он обеспечивает функциональность чистого кэша. Так что вместо использования require-reload
вам нужно только установить
before(function() {
mockery.enable({
warnOnReplace: false,
useCleanCache: true
});
});
а также require
обычно модуль, который загружает ваш mocked-модуль. в after
крючок вашего os
описать нужно позвонить mockery.resetCache
after(function(){
mockery.deregisterMock(windowsOsMock);
mockery.resetCache();
});
Я считаю, что это лучший способ решить этот сценарий, используя mockery
модуль