繁体   English   中英

测试包含异步代码的构造函数

[英]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");

        }
    })*/

}

我的测试用例如下:

  1. userType匹配User.userTypes第一个元素
  2. userType与User.userTypes另一个元素匹配(我选择了最后一个)
  3. userType与任何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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM