【问题标题】:Mock function return in node.js testnode.js 测试中的模拟函数返回
【发布时间】:2014-09-22 10:44:19
【问题描述】:

我是在 node.js 中进行测试的新手,我想在如下所示的过程中模拟特定函数调用的返回。

doSomething(function(err, res){
    callAnotherOne(res, function(err, result){
        getDataFromDB(result, function(err, docs){
            //some logic over the docs here
        })
    })
})

我要模拟的函数是 getDataFromDB(),特别是它返回的文档(使用 MongoDB)。 我怎么能用摩卡做这样的事情?

从中间的逻辑中剥离出来的部分代码如下:

filterTweets(item, input, function(err, item) {
    //Some filtering and logging here

    db.getTwitterReplies(item, function(err, result) {
        if(err) {
            return callback('Failed to retrieve tweet replies');
        }

        //Do some work here on the item using the result (tweet replies)

        /***** Here I want to test that the result is the expected ****/

        db.storeTweets(item function (err, result){
            //error checks, logging
            callback();
        });
    });
});

根据 twitter 回复的数量(函数调用“getTwitterReplies”),我将相应地修改我的对象(不包括该代码)。我想看看是否基于不同的回复结果,我的对象是否按预期构造。

附言经过一番搜索,我还检查了 sinon.js,我设法模拟了回调的返回(通过在我的项目之外编写一些测试代码),但没有模拟嵌套函数调用的回调的返回。

【问题讨论】:

  • 如果没有看到这一切如何联系在一起的示例,我真的想不出一个解决方案。
  • 我通过添加我想模拟的代码来编辑我的答案。
  • require() 的作用域可以提供一种在 sinon.js 测试中轻松进行依赖注入的方法,而无需引入大量额外的函数参数。我将在这些方面提供更广泛的答案。

标签: node.js unit-testing mocha.js sinon


【解决方案1】:

以下是我处理此类问题的方法:

首先创建一个“config.js”来包装您想要注入的依赖项。这将成为您的容器。

 var db = {
    doSomeDbWork : function(callback){
      callback("db data");
    }
 };

 module.exports = {
   db: db
 };

从那里,您可以像这样调用配置依赖项: var config = require('./index/config'); config.db.doSomeDbWork(函数(数据){ res.render('index', { title: 'Express' , data:data}); });

在您的测试中,轻松注入模拟/间谍:

var config = require('../routes/index/config');
config.db = {
  doSomeDbWork : function(callback){
    callback("fake db data");  
  }
};
var indexRouter = require('../routes/index');
indexRouter.get('/');

因为 require 调用引用相同的配置模块导出,所以对规范中的配置所做的更改将反映在通过 require() 导入的任何位置

【讨论】:

  • 我试过模拟模块,但它不是那么灵活。我将不得不为每个测试场景创建模拟模块。最重要的是,我想使用模块的非模拟方法。我现在正在看“proxyquire”,它实际上似乎为我完成了这项工作。
  • Proxyquire 实际上看起来非常适合这种情况。类似于这种方法,没有额外的模块包装器开销。
猜你喜欢
  • 2014-01-09
  • 2017-11-09
  • 2018-05-12
  • 1970-01-01
  • 1970-01-01
  • 2018-12-28
  • 1970-01-01
  • 1970-01-01
  • 2012-05-09
相关资源
最近更新 更多