嘲笑os.type()不工作

我试图unit testing一个依赖于底层操作系统的模块。

我试图使用嘲笑模拟os.type()返回基于不同的testing夹具的Linux / Windows_NT。

我正在使用摩卡作为我的unit testing框架。

我有一个描述部分,unit testing我的模块的functionA,其中有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(); }); }); }); }); 

我需要在每个操作系统相关的testing夹具之前testing的模块的原因是因为模块在全局范围内使用OS模块来决定一些variables值,如下所示:

 var os = require('os'); var osType = os.type(); /* decide variable values based on os.type() return value */ 

所以, 我认为,除非我再次需要它,在每个灯具之前,它将装载原先加载的OS模块,而不是我的模拟。

现在的问题是,它不能代替模块中的OS模块,我不知道为什么。

发生这种情况是因为在顶部你做var module_we_test = require('...'); 。 这将加载原始模块并将其保存在caching中。 所以,即使你嘲笑它,每当你需要它,你会得到caching的原始模块。 您需要首先使用嘲笑来模拟模块,然后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的文档之后,似乎它提供了干净的cachingfunction。 所以,而不是使用require-reload你只需要设置

 before(function() { mockery.enable({ warnOnReplace: false, useCleanCache: true }); }); 

并且通常require加载模拟模块的模块。 在os描述之后,你需要调用mockery.resetCache

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

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