嘲笑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
模块来解决这种情况的最好方法