如何使用 Mocha 对 node.js 函数进行单元测试?

How can I unit test node.js functions with Mocha?

我正在尝试测试如下所示的函数:

function sendVerifySms(patientId, data) {
    var smsNumber = data.smsNumber;
    var verifyCode = ((Math.random() * 1000000) | 0).toString();

    var sql = "UPDATE [patient]";
    sql += " SET phone_sms_verify_code = '" + verifyCode + "',";
    // verification must take place within a one hour period
    sql += " phone_sms_verify_code_expire = '" + moment.utc().add(1, 'hour').formatSqlDatetime() + "',";
    sql += " phone_sms_verified = 0,"
    sql += " phone_sms = '" + escapeSql(smsNumber) + "'";
    sql += " WHERE id = " + escapeSql(patientId.toString());

    return sqlServer.query(sql).then(function(result) {
        twilioClient.sendMessage({
            to: smsNumber,
            from: twilioUser.verifyNumber,
            body: verifyCode
        }).then(function(res) {
            console.log('sent verification');
            return verifyCode;
        }).fail(function(err) {
            console.log('error sending verification');
            console.log(err);
            return err;
        });
    }).fail(function(err) {
        console.log(err);
        return err;
    });
}

很简单,对吧?好吧,首先我需要确定我要测试的到底是什么。

  1. sql 命令与给定的格式匹配 data
  2. 已调用 twilioClient.sendMessage

这是我目前的测试结果:

var should = require('should');
var methods;
var mockery = require('mockery');
var sinon = require('sinon');

describe('RPC Methods', function() {
    before(function() {
        mockery.enable();
        mockery.registerMock('msnodesql', {
            open: function() {
                return true;
            }
        });

        mockery.registerMock('../../db/sqlserver', {
            query: function() {
                return {
                    then: function() {
                        return true;
                    }
                }
            }
        });

        methods = require('../../../rpc/methods');
    });

    it('should send a verify SMS', function() {
        var data = {

        }

        methods.sendVerifySms(1, data);
        should(1).equal(1);
    });
});

所以现在我有点迷路了。我有很多 require 并且因为我想隔离我的个人功能进行测试,所以我认为 mockery 这样的东西会起作用。我从这里去哪里?

如果有任何不清楚的地方,请post发表评论,我会澄清。

谢谢!

对于 mocha 测试,您有一个可选的 done 回调,它使测试异步函数更容易,如下所示:

it('should send a verify SMS', function(done) {
    var data = {};
    var code = 1;
    methods.sendVerifySms(code, data)
        .then(function(actualCode) {
            should(actualCode).equal(code);
            done();
        });
});

我还会对您正在测试的异步函数提供一些反馈。首先,我会说您不必像现在这样嵌套承诺链,在这种情况下,最好不要这样做。如果您只是 return 来自 promise 回调的 promise,您可以将它链接在同一级别,如下所示:

return sqlServer.query(sql).then(function(result) {
    return twilioClient.sendMessage({
        to: smsNumber,
        from: twilioUser.verifyNumber,
        body: verifyCode
    });
}).then(function(res) {
    console.log('sent verification');
    return verifyCode;
}).fail(function(err) {
    console.log(err);
    throw err;
});

其次,在您只是 returning 错误之前的错误处理程序中。这可能是个坏主意,因为它告诉消费者您的承诺,即一切都很好,他们应该照此进行。另一方面,抛出错误将允许该消费者在他们自己的 .fail 块中按照他们想要的方式处理错误。