Издевательство над издевательством 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 модуль

Другие вопросы по тегам