【问题标题】:Node-Redis Asynchrounous testing using mocha使用 mocha 进行 Node-Redis 异步测试
【发布时间】:2014-03-19 03:37:05
【问题描述】:

我有一个用 Node.JS 编写的简单异步代码,它将一个字符串添加到 Redis SET 中。这是代码,它保存在一个名为 redis_ops.js 的文件中

 var redis = require('redis');
 exports.addUser= function(){
    var client = redis.createClient();
    client.on("error",function(err){
        console.log('Error'+ err);
    });
   client.select(1);
   client.sadd("users","naveen",function(err,reply){
        if(err)
            throw err;
        return reply;

   });
  console.log("at the end of the adduser function")
  }

由于 client.sadd 是异步的,所以包含 client.sadd 的函数会在 client.sdd 完成之前返回。 这是使用 Mocha 编写的测试

var assert = require("assert");
var core = require('./redis_ops.js');

describe('COREAPI', function(){
    describe('addUser', function(){
        it('should return 1 if the user is added successfully', function(){
        assert.equal(1,core.addUser() );

    })
  })
})

测试失败,因为 redis_ops 返回 undefined (无返回值),因为包含 client.sadd 的函数首先返回,异步 client.sadd 稍后返回要在测试中断言的预期值。如何在不重复代码或不包含同一文件中的所有代码的情况下测试异步 client.sadd 的返回值?

【问题讨论】:

    标签: node.js asynchronous mocha.js node-redis


    【解决方案1】:

    Mocha 允许您使用可选的回调来测试异步函数。

    describe('COREAPI', function () {
        describe('addUser', function () {
            it('should return 1 if the user is added successfully', function (done) {
                core.addUser(function (err, result) {
                    assert.ifError(err);
                    assert.equal(result, 1);
                    done();
                });
            });
        });
    });
    

    您的 redis_ops.js 文件有问题。您不得向异步函数抛出回调。按照惯例,回调可能只将错误作为第一个参数(如果没有错误,则返回 null),并将其他参数作为结果。

    即使您尝试捕获它,代码中的 throw 也会导致未捕获的异常,因为 try-catch 仅适用于同步代码。您必须将其重新格式化为:

    var client = require('redis').createClient();
    
    client.on('error', function (err) {
        console.error(err);
    });
    
    exports.addUser = function () {
        client.select(1, function (err) {
            if (err) {
                return callback(err)
            }
    
            client.sadd('users', 'naveen', function (err, reply) {
                if (err) {
                    return callback(err);
                }
    
                console.log('at the end of the adduser function')
    
                callback(null, reply);
            });
        });
    };
    

    或者使用 redis 模块的client.multi 批处理工具,exports.addUser 可能看起来像:

    exports.addUser = function () {
        var multi = client.multi();
    
        multi.select(1).sadd('users', 'naveen').exec(function (err, results) {
            if (err) {
                return callback(err);
            }
    
            callback(null, results[1]);
        });
    };
    

    【讨论】:

    • 非常感谢您帮助我理解测试异步代码。非常有帮助的答案。
    • 一方面core.addUser(function (err, result) {...,另一方面exports.addUser = function () {...。可能缺少callback 参数?此外,client.on("error", function (err) { callback(err); }); 无法工作,因为范围内没有callback
    • @Louis 是的,callback 应该是 console.errorcore 是正确的,因为大概core 是我们将函数附加到导出的模块的名称。即顶部列表在一个测试模块中,下面两个在core 模块中。
    • @KarthicRao 没问题。 :)
    • 它正在删除行 "assert.ifError(err)" ,但无法理解为什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-05
    • 1970-01-01
    • 1970-01-01
    • 2014-02-06
    • 2018-09-22
    • 2016-02-21
    相关资源
    最近更新 更多