[英]Testing a constructor that contains asynchronous code
我正在尝试在使用异步代码的node.js中测试构造函数,以测试其中的功能。 我知道异步代码有效,因为在我加入功能之前,我已经运行了它,就好像我是最终用户一样。 实际上,我感谢一位回答了我另一个问题的用户
功能
User
构造函数有一个userRole
成员,以及一些异步代码,用于根据User.userTypes
检查指定的userType
。 如果找到userType
,则this.userRole
设置为userType
。 否则,抛出异常。
代码如下:
async.forEachSeries(
User.userTypes,
function(user_type, callback)
{
if (user_type == userType)
{
this.userRole = user_type;
return;
}
if (user_type == User.userTypes[User.userTypes.length - 1])
{
callback(helpers.invalidData("user_role"));
return;
}
callback(null);
},
function(err)
{
if (err)
{
if (DEBUG)
{
console.log("Error from constructor...");
console.log(JSON.stringify(err, null, '\t') + "\n");
}
throw err;
}
}
);
其余的构造函数如下所示:
function User(id, email, displayName, password, userType, deleted, cb)
{
var DEBUG = true;
var error = null;
this.userID = id;
this.email = email;
this.displayName = displayName;
this.deleted = deleted;
var self = this;
async.forEachSeries(
User.userTypes,
function(user_type, callback)
{
if (user_type == userType)
{
this.userRole = user_type;
return;
}
if (user_type == User.userTypes[User.userTypes.length - 1])
{
callback(helpers.invalidData("user_role"));
return;
}
callback(null);
},
function(err)
{
if (err)
{
if (DEBUG)
{
console.log("Error from constructor...");
console.log(JSON.stringify(err, null, '\t') + "\n");
}
throw err;
}
}
);
if (User.connectedToDatabase) this._password = password;
else
{
bcrypt.genSalt(10, function (e, salt) {
bcrypt.hash(password, salt, function (e, hash) {
if (!e)
{
self._password = hash;
if (DEBUG)
{
console.log("this._password ==" + self._password);
console.log("this.userID == " + self.userID);
}
if (typeof cb === 'function')
cb(null, this);
}
else
{
console.log("Error occurred: ");
console.log(e);
if (typeof cb === 'function')
cb(e);
}
})
});
}
}
User.connectedToDatabase = false;
User.BASIC = "basic user";
User.INVENTORY_MANAGEMENT = "inventory";
User.ADMIN = "admin";
User.userTypes = [ User.BASIC, User.INVENTORY_MANAGEMENT, User.ADMIN ];
User.prototype.userID = 0;
User.prototype.email = null;
User.prototype.displayName = null;
User.prototype._password = null;
User.prototype.userRole = User.BASIC;
User.prototype.deleted = false;
User.prototype.responseObject = function() {
return {
id: this.userID,
email: this.email,
displayName: this.displayName,
userType: this.userRole
};
}
我的测试
我编写了test()
函数,该函数接受要传递给User
参数。 如果User
构造没有错误,它将连同其某些成员一起打印到控制台。 否则,将打印错误。 这是代码:
function test(email, name, pass, type)
{
try
{
var a = new User(Math.round(Math.random() * 32),
email,
name,
pass,
type
);
console.log("Test user created: " + JSON.stringify(a.responseObject(), null, '\t') + "\n");
console.log("User._password == " + a._password);
console.log("\n");
}
catch (e)
{
console.log("User could not be created.\n" + JSON.stringify(e, null, '\t') + "\n");
}
/*async.waterfall([
function(callback){
var a = new User(Math.round(Math.random * 32),
email,
name,
pass,
type);
callback(null, a);
},
function(a, callback) {
console.log("Test user created: " + JSON.stringify(a, null, '\t') + "\n");
console.log("User._password == " + a._password);
console.log("User.userID == " + a.userID);
console.log("\n");
callback(null, a);
}
],
function(err, results)
{
console.log("results of test: " + JSON.stringify(results, null, '\t'));
if (err)
{
console.log("User could not be created.\n" + JSON.stringify(err, null, '\t') + "\n");
}
})*/
}
我的测试用例如下:
User.userTypes
第一个元素 User.userTypes
另一个元素匹配(我选择了最后一个) User.userTypes
不匹配 在运行时,创建新用户后, User._password
是默认值,而不是异步代码为其提供的值。 我怀疑我有一些异步同步错误,但无法修复。
由于@Bergi的建议,已将其修复。
我做的第一件事:在那个async.forEachSeries()
,我this
实例更改为self
。
我做的第二件事:将异步代码(正在运行!)替换为同步代码。 代替这个:
bcrypt.genSalt(10, function (e, salt) {
bcrypt.hash(password, salt, function (e, hash) {
if (!e)
{
self._password = hash;
if (DEBUG)
{
console.log("this._password ==" + self._password);
console.log("this.userID == " + self.userID);
}
if (typeof cb === 'function')
cb(null, this);
}
else
{
console.log("Error occurred: ");
console.log(e);
if (typeof cb === 'function')
cb(e);
}
})
});
我只是简单地说: this._password = bcrypt.hashSync(password, bcrypt.genSaltSync(10));
一切都很好!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.