嘲弄 os.type() 不起作用

Posted

技术标签:

【中文标题】嘲弄 os.type() 不起作用【英文标题】:Mockery mocking os.type() is not working 【发布时间】:2016-08-08 10:06:43 【问题描述】:

我正在尝试对我的一个依赖于底层操作系统的模块进行单元测试。

我正在尝试使用 mockery 来模拟 os.type() 以根据不同的测试装置返回 Linux/Windows_NT。

我使用 mocha 作为我的单元测试框架。

我有一个描述部分,它对我的​​模块的功能 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 */

所以,我认为除非我再次需要它,否则在每个夹具之前它都会加载最初加载的 OS 模块而不是我的模拟。

现在,问题是它只是没有替换模块中的 OS 模块,我不知道为什么。

【问题讨论】:

除了被测模块之外,您是否将os模块加载到其他模块中? 【参考方案1】:

发生这种情况是因为您在顶部执行var module_we_test = require('...');。这将加载原始模块并将其保存在缓存中。因此,即使您每次需要它时都使用 mockery 来模拟它,您也会取回缓存的原始模块。您需要先使用 mockery 来模拟模块,然后 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 通常是加载你的模拟模块的模块。在osafter 钩子中描述你需要调用mockery.resetCache

after(function()
    mockery.deregisterMock(windowsOsMock);
    mockery.resetCache();
); 

我相信这是使用mockery 模块解决这种情况的最佳方法

【讨论】:

我已经按照你的建议使用了重新加载,我在每个与特定操作系统相关的测试夹具之前重新加载它,但是当我调试 Linux 夹具时,我仍然将 Windows_NT 作为我的 osType,我更新了操作 @Jorayen 不要忘记在描述块中注销您的模拟。 仍然无法正常工作,我不知道我在第一次使用嘲弄时做错了什么,如果您能给我写一个工作模板会很有帮助 @Jorayen 我添加了一个在我的机器上运行的工作示例。希望有帮助。此外,无需在文件顶部重新加载 module_we_test。看看我在我的例子中做了什么 太棒了!似乎需要文件顶部的 module_we_test 导致问题,而不是仅在夹具范围内使用它。

以上是关于嘲弄 os.type() 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

嘲弄 shouldReceive()->once() 似乎不起作用

transpportrule不起作用

PHP.INI不起作用

C#DataGridView的行列表头背景色字体色不起作用

关于Animate css不起作用的原因

修改php.ini不起作用是为啥