【问题标题】:nodejs - mocking modules, naive approachnodejs - 模拟模块,天真的方法
【发布时间】:2013-11-25 20:17:27
【问题描述】:

目前我正在为使用nodejs 编写的服务器端代码编写一些单元测试。

现在,我的自定义模块正在使用其他一些模块,我的或来自nodejs 标准库的模块,我想模拟它们。首先,我搜索了一些现有的解决方案,例如我发现:https://github.com/thlorenz/proxyquirehttps://github.com/mfncooper/mockery

但今天我尝试使用幼稚的方法并做这样的事情:moduleUnderTest

var fs = require('fs');
exports.foo = function(){
  console.log("===foo===");
  fs.read();
}

和文件moduleUnderTestSpec:

var fs = require('fs');
var moduleUnderTests = require('../server/moduleUnderTests.js');

fs.read = function(){
  console.log("===read===");
}

当我运行grunt jasmine_node 时,我可以看到:

===foo===
===read===

所以在这个简单的例子中,我可以将fs 模块中的一个函数换成另一个。有没有我的方法行不通的情况?

【问题讨论】:

    标签: node.js unit-testing mocking


    【解决方案1】:

    首先查看sinon,因为它可以帮助您轻松地模拟或存根函数。

    当您在 Node.js 中 require 一个模块时,模块会根据 docs on modules 进行缓存。

    我在您的解决方案中看到的唯一问题是,稍后如果您需要使用真正的fs.read,您将无法使用它,因为它已经丢失了。比如你可以像这样使用诗乃;

    var fs = require('fs');
    var sinon = require('sinon');
    
    // mock fs.read
    sinon
      .stub(fs, 'read')
      .returns("string data");
    
    // test your code that uses fs.read
    assert(fs.read.calledOnce);
    
    // then restore
    fs.read.restore();
    

    【讨论】:

      【解决方案2】:

      您的方法还可以,但只有在模块导出对象时才有效。如果一个模块导出函数(经常发生)或其他任何东西,你就不能模拟它。也就是说,您只能模拟模块对象的一个​​属性,而不能模拟整个对象。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-29
      • 2017-12-30
      • 2019-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-05
      相关资源
      最近更新 更多