如何使用 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;
});
}
很简单,对吧?好吧,首先我需要确定我要测试的到底是什么。
sql
命令与给定的格式匹配 data
- 已调用
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
块中按照他们想要的方式处理错误。
我正在尝试测试如下所示的函数:
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;
});
}
很简单,对吧?好吧,首先我需要确定我要测试的到底是什么。
sql
命令与给定的格式匹配data
- 已调用
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
块中按照他们想要的方式处理错误。