摩卡测试执行时间太长

时间:2015-03-06 01:09:16

标签: node.js mongodb express mongoose mocha

所以我正在使用express.js应用程序,我有一个猫鼬模型用户。我编写了一个测试文件(使用Mocha)来测试save()函数,但是我的所有测试都花了很长时间才能执行并最终超时。

以下是我遇到的错误:

  Testing - Server - User - Model
    Testing save()
      1) should be able to save without problems
      2) should fail to save an exisitng user again
      3) should should an error when try to save with empty email
      4) should give an error when try to save with empty password
    5) "after all" hook


  0 passing (8s)
  5 failing

  1) Testing - Server - User - Model Testing save() should be able to save without problems:
     Error: timeout of 2000ms exceeded
      at null.<anonymous> (/usr/local/lib/node_modules/mocha/lib/runnable.js:159:19)
      at Timer.listOnTimeout [as ontimeout] (timers.js:112:15)

  2) Testing - Server - User - Model Testing save() should fail to save an exisitng user again:
     Error: timeout of 2000ms exceeded
      at null.<anonymous> (/usr/local/lib/node_modules/mocha/lib/runnable.js:159:19)
      at Timer.listOnTimeout [as ontimeout] (timers.js:112:15)

  3) Testing - Server - User - Model Testing save() should should an error when try to save with empty email:
     Error: timeout of 2000ms exceeded
      at null.<anonymous> (/usr/local/lib/node_modules/mocha/lib/runnable.js:159:19)
      at Timer.listOnTimeout [as ontimeout] (timers.js:112:15)

  4) Testing - Server - User - Model Testing save() should give an error when try to save with empty password:
     Uncaught AssertionError: expected null to exist
      at Promise.<anonymous> (/Users/Mukul/PersonalProjects/ResourceBucket/test/models/user.server.model.test.js:69:12)
      at Promise.<anonymous> (/Users/Mukul/PersonalProjects/ResourceBucket/node_modules/mongoose/node_modules/mpromise/lib/promise.js:177:8)
      at Promise.emit (events.js:98:17)
      at Promise.emit (/Users/Mukul/PersonalProjects/ResourceBucket/node_modules/mongoose/node_modules/mpromise/lib/promise.js:84:38)
      at Promise.fulfill (/Users/Mukul/PersonalProjects/ResourceBucket/node_modules/mongoose/node_modules/mpromise/lib/promise.js:97:20)
      at handleSave (/Users/Mukul/PersonalProjects/ResourceBucket/node_modules/mongoose/lib/model.js:133:13)
      at /Users/Mukul/PersonalProjects/ResourceBucket/node_modules/mongoose/lib/utils.js:408:16
      at model.save (/Users/Mukul/PersonalProjects/ResourceBucket/node_modules/mongoose/lib/model.js:222:7)
      at model._done (/Users/Mukul/PersonalProjects/ResourceBucket/node_modules/mongoose/node_modules/hooks/hooks.js:59:24)
      at _next (/Users/Mukul/PersonalProjects/ResourceBucket/node_modules/mongoose/node_modules/hooks/hooks.js:52:28)
      at fnWrapper (/Users/Mukul/PersonalProjects/ResourceBucket/node_modules/mongoose/node_modules/hooks/hooks.js:159:8)
      at model.<anonymous> (/Users/Mukul/PersonalProjects/ResourceBucket/models/user.js:22:46)
      at _next (/Users/Mukul/PersonalProjects/ResourceBucket/node_modules/mongoose/node_modules/hooks/hooks.js:50:30)
      at fnWrapper (/Users/Mukul/PersonalProjects/ResourceBucket/node_modules/mongoose/node_modules/hooks/hooks.js:159:8)
      at complete (/Users/Mukul/PersonalProjects/ResourceBucket/node_modules/mongoose/lib/document.js:992:5)
      at /Users/Mukul/PersonalProjects/ResourceBucket/node_modules/mongoose/lib/document.js:983:20
      at ObjectId.SchemaType.doValidate (/Users/Mukul/PersonalProjects/ResourceBucket/node_modules/mongoose/lib/schematype.js:603:22)
      at /Users/Mukul/PersonalProjects/ResourceBucket/node_modules/mongoose/lib/document.js:974:9
      at process._tickCallback (node.js:442:13)

  5) Testing - Server - User - Model "after all" hook:
     Error: timeout of 2000ms exceeded
      at null.<anonymous> (/usr/local/lib/node_modules/mocha/lib/runnable.js:159:19)
      at Timer.listOnTimeout [as ontimeout] (timers.js:112:15)

这是我的测试文件:

// Module dependencies
var should = require("should");
var mongoose = require("mongoose");
var config = require('../../config/config');
var nodemailer = require('nodemailer');
var bcrypt = require('bcryptjs');

// Get User model
var User = require('../../models/user')(mongoose, config, bcrypt, nodemailer).User;

// Define global test variables
var user;
var user2;

// Unit tests
describe('Testing - Server - User - Model', function(){

    // Since its before - it happens once ONCE before ALL the tests
    before(function(done){
        // Since we're using the global variables don't use var in front of them
        user = new User({
            email: 'a@a.com',
            password: 'a'
        });

        // Another user with same details as the first user cos
        // For a test case, where we try to insert 2 records with same details (should fail as exprected)
        user2 = new User({
            email: 'a@a.com',
            password: 'a'
        });
        done();
    });

    // Testing function #1 - save()
    describe('Testing save()', function(){

        // Test case #1 - save normally
        it('should be able to save without problems', function(done){
            try { 
                user.save(done);
            } catch (x) { 
                done(x);
            }
        });

        // Test case #2 - should fail to save an exisitng user again
        it('should fail to save an exisitng user again', function(done){
            user.save(function(){
                user2.save(function(err){
                    should.exist(err);
                    done();
                });
            });
        })

        // Test case #3 - should give an error when try to save with empty email
        it('should should an error when try to save with empty email', function(done){
            user.email = '';
            return user.save(function(err){
                should.exist(err);
                done();
            });
        });

        // Test case #4 - should give an error when try to save with empty password
        it('should give an error when try to save with empty password', function(done){
            return user.save(function(err){
                should.exist(err);
                done();
            });
        });
    });

    after(function(done){
        User.remove().exec(done);
    });
});

这是我的用户模型文件:

module.exports = function(mongoose, config, bcrypt, nodemailer){

  // User schema 
  var userSchema = new mongoose.Schema({
    email: {
      type: String,
      unique: true,
      lowercase: true
    },
    password: {
      type: String,
      select: false
    }
  });

  // Makes sure that our passwords are always hashed before saving to the database
  // Refer to sessionBuddy's resources for more info on this 
  userSchema.pre('save', function(next) {
    var user = this;

    // Only hash the password if its modified or new
    if (!user.isModified('password')) return next();

    // Generate salt
    bcrypt.genSalt(config.SALT_WORK_FACTOR, function(err, salt) {
      if (err) return next(err);

      // hash the password along with the salt
      bcrypt.hash(user.password, salt, function(err, hash) {
        if (err) return next(err);

        // overwrite the cleartext password with the hashed one
        user.password = hash;
        next();
      });
    });
  });

  // Password verification for cleartext and hashed passwords
  userSchema.methods.comparePassword = function(password, done) {
    bcrypt.compare(password, this.password, function(err, isMatch) {
      done(err, isMatch);
    });
  };

  var User = mongoose.model('User', userSchema);

  return{
    User : User
  }
}

我也试过了来自这个帖子的承诺的try / catch方式:In mocha testing while calling asynchronous function how to avoid the timeout Error: timeout of 2000ms exceeded.但是那也没有用。

任何帮助表示赞赏! 感谢

编辑:正如评论中所建议的那样,我没有连接到测试文件中的数据库。 EDIT2:现在最后2个测试出现以下错误 - &#34; Uncaught AssertionError:预期存在null&#34; EDIT3:实际上我的架构可以保存&#34;电子邮件&#34;和#34;密码&#34;因为我没有将必填字段设置为true,所以在更新我的模式后,它可以正常工作。

1 个答案:

答案 0 :(得分:1)

正如评论中指出的那样,您实际上并没有连接到mongodb数据库。您的所有请求都将由Mongoose排队,并且在您连接到数据库之前永远不会被执行(从而在测试中生成超时)。

修改 至于你的第二个问题,当你实际上没有产生任何错误时,你预计会存在错误。这条线未通过测试:

should.exist(err);

您应该检查您的型号。在您的第三个测试用例中,您需要用户收到电子邮件,但您的模型并未强制执行此操作。密码也一样。 此外,您没有在测试中将密码设置为空。