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

时间:2016-08-03 19:04:26

标签: javascript node.js asynchronous

我试图在node.js中测试一个使用异步代码的构造函数,以测试其中的一个特性。我知道异步代码是有效的,因为我已经运行它,在我输入该功能之前,就好像我是最终用户一样。 In fact, I got it thanks to some user who answered another question I had

功能

User构造函数有一个userRole成员,以及一些异步代码,用于检查userType指定的User.userTypes。如果找到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. 的第一个元素
  3. userType匹配User.userTypes的另一个元素(我选择了最后一个)
  4. userType与User.userTypes
  5. 中的任何一个都不匹配

    在运行时,在创建新用户之后,User._password是默认值,而不是我的异步代码为它提供的值。Sample run我怀疑我有一些异步同步错误,但避免&# 39;能够解决它。

1 个答案:

答案 0 :(得分:0)

得到了解决,感谢@ 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));,一切都很好!