Mocha 测试执行时间太长

Mocha tests taking too long to execute

所以我正在开发一个 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 次测试出现以下错误 - "Uncaught AssertionError: expected null to exist" EDIT3:实际上我的模式可以将 "email" 和 "password" 保存为空,因为我没有将必填字段设置为 true,在更新我的模式后,它可以工作。

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

编辑 至于你的第二个问题,当它实际上没有产生任何错误时,你期望错误存在。此行未通过您的测试:

should.exist(err);

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