2016-04-12 61 views
-1

我寫摩卡代碼進行測試登錄和註冊系統:
以下是代碼:
controllers/account.jsNode.js的摩卡測試:的ReferenceError:會議沒有定義

var AccountController = function(userModel, session, mailer) { 

    this.crypto = require('crypto'); 
    this.uuid = require('node-uuid'); 
    this.ApiResponse = require('../models/api-response.js'); 
    this.ApiMessages = require('../models/api-messages.js'); 
    this.UserProfileModel = require('../models/user-profile.js'); 
    this.userModel = userModel; 
    this.session = session; 
    this.mailer = mailer; 
}; 

module.exports = AccountController; 

//gets the current session 
AccountController.prototype.getSession = function() { 
    return this.session; 
}; 

//sets the current session 
AccountController.prototype.setSession = function(session) { 
    this.session = session; 
}; 

//Creates cryptographically-strong pseudo random hash of the password 
AccountController.prototype.hashPassword = function(password, salt, callback) { 
    // we use pbkdf2 to hash and iterate 10k times by default 
    var iterations = 10000, 
     keyLen = 64; // 64 bit. 
    this.crypto.pbkdf2(password, salt, iterations, keyLen, callback); 
}; 

//log in method 
AccountController.prototype.logon = function(email, password, callback) { 

    var me = this; 

    me.userModel.findOne({ 
     email: email 
    }, function(err, user) { 

     if (err) { 
      return callback(err, new me.ApiResponse({ 
       success: false, 
       extras: { 
        msg: me.ApiMessages.DB_ERROR 
       } 
      })); 
     } 

     if (user) { 

      me.hashPassword(password, user.passwordSalt, function(err, passwordHash) { 

       if (passwordHash == user.passwordHash) { 

        var userProfileModel = new me.UserProfileModel({ 
         email: user.email, 
         firstName: user.firstName, 
         lastName: user.lastName 
        }); 

        me.session.userProfileModel = userProfileModel; 

        return callback(err, new me.ApiResponse({ 
         success: true, 
         extras: { 
          userProfileModel: userProfileModel 
         } 
        })); 
       } else { 
        return callback(err, new me.ApiResponse({ 
         success: false, 
         extras: { 
          msg: me.ApiMessages.INVALID_PWD 
         } 
        })); 
       } 
      }); 
     } else { 
      return callback(err, new me.ApiResponse({ 
       success: false, 
       extras: { 
        msg: me.ApiMessages.EMAIL_NOT_FOUND 
       } 
      })); 
     } 

    }); 
}; 

//log off method 
AccountController.prototype.logoff = function() { 
    if (this.session.userProfileModel) delete this.session.userProfileModel; 
    return; 
}; 

//register method 
AccountController.prototype.register = function(newUser, callback) { 
    var me = this; 
    me.userModel.findOne({ 
     email: newUser.email 
    }, function(err, user) { 

     if (err) { 
      return callback(err, new me.ApiResponse({ 
       success: false, 
       extras: { 
        msg: me.ApiMessages.DB_ERROR 
       } 
      })); 
     } 

     if (user) { 
      return callback(err, new me.ApiResponse({ 
       success: false, 
       extras: { 
        msg: me.ApiMessages.EMAIL_ALREADY_EXISTS 
       } 
      })); 
     } else { 

      newUser.save(function(err, user, numberAffected) { 

       if (err) { 
        return callback(err, new me.ApiResponse({ 
         success: false, 
         extras: { 
          msg: me.ApiMessages.DB_ERROR 
         } 
        })); 
       } 

       if (numberAffected === 1) { 

        var userProfileModel = new me.UserProfileModel({ 
         email: user.email, 
         firstName: user.firstName, 
         lastName: user.lastName 
        }); 

        return callback(err, new me.ApiResponse({ 
         success: true, 
         extras: { 
          userProfileModel: userProfileModel 
         } 
        })); 
       } else { 
        return callback(err, new me.ApiResponse({ 
         success: false, 
         extras: { 
          msg: me.ApiMessages.COULD_NOT_CREATE_USER 
         } 
        })); 
       } 

      }); 
     } 

    }); 
}; 

//reset password method 
AccountController.prototype.resetPassword = function(email, callback) { 
    var me = this; 
    me.userModel.findOne({ 
     email: email 
    }, function(err, user) { 

     if (err) { 
      return callback(err, new me.ApiResponse({ 
       success: false, 
       extras: { 
        msg: me.ApiMessages.DB_ERROR 
       } 
      })); 
     } 

     // Save the user's email and a password reset hash in session. We will use 
     var passwordResetHash = me.uuid.v4(); 
     me.session.passwordResetHash = passwordResetHash; 
     me.session.emailWhoRequestedPasswordReset = email; 

     me.mailer.sendPasswordResetHash(email, passwordResetHash); 

     return callback(err, new me.ApiResponse({ 
      success: true, 
      extras: { 
       passwordResetHash: passwordResetHash 
      } 
     })); 
    }) 
}; 

/*Users will invoke this method when they access a special web page using the 「password reset」 link 
inside the email that they will receive after they perform the first step of the password reset 
process*/ 
AccountController.prototype.resetPasswordFinal = function(email, newPassword, passwordResetHash, callback) { 
    var me = this; 
    if (!me.session || !me.session.passwordResetHash) { 
     return callback(null, new me.ApiResponse({ 
      success: false, 
      extras: { 
       msg: me.ApiMessages.PASSWORD_RESET_EXPIRED 
      } 
     })); 
    } 

    if (me.session.passwordResetHash !== passwordResetHash) { 
     return callback(null, new me.ApiResponse({ 
      success: false, 
      extras: { 
       msg: me.ApiMessages.PASSWORD_RESET_HASH_MISMATCH 
      } 
     })); 
    } 

    if (me.session.emailWhoRequestedPasswordReset !== email) { 
     return callback(null, new me.ApiResponse({ 
      success: false, 
      extras: { 
       msg: me.ApiMessages.PASSWORD_RESET_EMAIL_MISMATCH 
      } 
     })); 
    } 

    var passwordSalt = this.uuid.v4(); 

    me.hashPassword(newPassword, passwordSalt, function(err, passwordHash) { 

     me.userModel.update({ 
      email: email 
     }, { 
      passwordHash: passwordHash, 
      passwordSalt: passwordSalt 
     }, function(err, numberAffected, raw) { 

      if (err) { 
       return callback(err, new me.ApiResponse({ 
        success: false, 
        extras: { 
         msg: me.ApiMessages.DB_ERROR 
        } 
       })); 
      } 

      if (numberAffected < 1) { 

       return callback(err, new me.ApiResponse({ 
        success: false, 
        extras: { 
         msg: me.ApiMessages.COULD_NOT_RESET_PASSWORD 
        } 
       })); 
      } else { 
       return callback(err, new me.ApiResponse({ 
        success: true, 
        extras: null 
       })); 
      } 
     }); 
    }); 
}; 

test/user-mock.js

var UserMock = function() { 

    this.uuid = require('node-uuid'); 
    this.crypto = require('crypto'); 
    this.User = require('../models/user.js'); 
    this.seedUsersCount = 10; 
    this.users = []; 
    this.err = false; 
    this.numberAffected = 0; 
}; 

UserMock.prototype.setError = function (err) { 
    this.err = err; 
}; 

UserMock.prototype.setNumberAffected = function (number) { 
    this.numberAffected = number; 
}; 

UserMock.prototype.seedUsers = function() { 
    for (var i = 0; i < this.seedUsersCount; i++) { 

     var passwordSaltIn = this.uuid.v4(), 
      cryptoIterations = 10000, // Must match iterations used in controller#hashPassword. 
      cryptoKeyLen = 64,  // Must match keyLen used in controller#hashPassword. 
      passwordHashIn; 

     var user = new this.User({ 
      email: 'Test' + i + '@test.com', 
      firstName: 'FirstName' + i, 
      lastName: 'LastName' + i, 
      passwordHash: this.crypto.pbkdf2Sync('Password' + i, passwordSaltIn, cryptoIterations, cryptoKeyLen), 
      passwordSalt: passwordSaltIn 
     }); 

     this.users.push(user); 
    } 
}; 

UserMock.prototype.getTestUser = function() { 
    return this.users ? this.users[0] : null; 
}; 

UserMock.prototype.findById = function (id, callback) { 

    for (var i = 0, length = this.users.length; i < length; i++) { 

     if (this.users[i]._id === id) { 
      return callback(this.err, this.users[i]); 
     } 
    }   

    return callback(this.err, null); 
}; 

UserMock.prototype.findOne = function (where, callback) { 

    for (var i = 0, length = this.users.length; i < length; i++) { 

     if (this.users[i].email === where.email) { 
      return callback(this.err, this.users[i]); 
     } 
    } 

    return callback(this.err, null); 
}; 

UserMock.prototype.save = function (callback) { 
    return callback(this.err, this, this.numberAffected); 
}; 

module.exports = UserMock; 

test/mailer-mock.js

var MailerMock = function() { }; 

MailerMock.prototype.sendPasswordResetHash = function (email, passwordResetHash) { }; 

module.exports = MailerMock; 

test/accounnt-controller-test.js

var AccountController = require('../controllers/account.js'), 
    mongoose = require('mongoose'), 
    should = require('should'), 
    uuid = require('node-uuid'), 
    crypto = require('crypto'), 
    User = require('../models/user.js'), 
    UserMock = require('./user-mock.js'), 
    MailerMock = require('./mailer-mock.js'), 
    ApiMessages = require('../models/api-messages.js'); 


describe('AccountController', function() { 
    var controller, 
     seedUsersCount = 10, 
     testUser, 
     userModelMock, 
     session = {}, 
     mailMock; 
}); 

beforeEach(function(done) { 
    userModelMock = new UserMock(); 
    mailerMock = new MailerMock(); 
    controller = new AccountController(userModelMock, session, mailerMock); 
    done(); 
}); 


afterEach(function(done) { 
    userModelMock.setError(false); 
    done(); 
}); 

it('Returns db error', function(done) { 

    userModelMock.setError(true); 
    userModelMock.seedUsers(); 
    var testUser = userModelMock.getTestUser(), 
     testUserPassword = 'Password0'; 

    controller.logon(testUser.email, testUserPassword, function(err, apiResponse) { 

     should(apiResponse.success).equal(false); 
     should(apiResponse.extras.msg).equal(ApiMessages.DB_ERROR); 
     done(); 
    }); 
}); 


/*logon method*/ 
AccountController.prototype.logon = function(email, password, callback) { 

    var me = this; 

    me.userModel.findOne({ email: email }, function (err, user) { 

     if (err) { 
      return callback(err, new me.ApiResponse({ success: false, extras: { msg: me.ApiMessages.DB_ERROR } })); 
     } 

     if (user) { 

      me.hashPassword(password, user.passwordSalt, function (err, passwordHash) { 

       if (passwordHash == user.passwordHash) { 

        var userProfileModel = new me.UserProfileModel({ 
         email: user.email, 
         firstName: user.firstName, 
         lastName: user.lastName 
        }); 

        me.session.userProfileModel = userProfileModel; 

        return callback(err, new me.ApiResponse({ 
         success: true, extras: { 
          userProfileModel:userProfileModel 
         } 
        })); 
       } else { 
        return callback(err, new me.ApiResponse({ success: false, extras: { msg: me.ApiMessages.INVALID_PWD } })); 
       } 
      }); 
     } else { 
      return callback(err, new me.ApiResponse({ success: false, extras: { msg: me.ApiMessages.EMAIL_NOT_FOUND } })); 
     } 

    }); 
}; 

當我運行在終端mocha,我得到以下錯誤:

1) "before each" hook for "Returns db error" 

0 passing (37ms) 
1 failing 

1) "before each" hook for "Returns db error": 
    ReferenceError: session is not defined 
    at Context.<anonymous> (D:\PhoneGap_Projects\login\www\server\test\account-controller-test.js:24:55) 
    at callFnAsync (C:\Users\Ajay Kulkarni-enEXL\AppData\Roaming\npm\node_modules\mocha\lib\runnable.js:338:8) 
    at Hook.Runnable.run (C:\Users\Ajay Kulkarni-enEXL\AppData\Roaming\npm\node_modules\mocha\lib\runnable.js:290:7) 
    at next (C:\Users\Ajay Kulkarni-enEXL\AppData\Roaming\npm\node_modules\mocha\lib\runner.js:298:10) 
    at Immediate._onImmediate (C:\Users\Ajay Kulkarni-enEXL\AppData\Roaming\npm\node_modules\mocha\lib\runner.js:320:5) 

我怎樣才能解決這個問題?

回答

1

您的會話對象在定義的測試範圍內是本地的。因爲mocha正在調用會話對象,因此它需要全局定義會話。

簡單來說將您define('AccountController')測試var session = {}

+0

哦......我沒看到...謝謝:) –