测试MongooseJs验证

7

有人知道如何测试Mongoose验证吗?

例如,我有以下模式(以示例为例):

var UserAccount = new Schema({
    user_name       : { type: String, required: true, lowercase: true, trim: true, index: { unique: true }, validate: [ validateEmail, "Email is not a valid email."]  }, 
    password        : { type: String, required: true },
    date_created    : { type: Date, required: true, default: Date.now }
}); 

validateEmail方法的定义如下:

// Email Validator
function validateEmail (val) {
    return /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/.test(val);
}

我想测试验证功能。最终结果是我想要能够测试验证,根据这些事件发生,我可以编写其他测试来测试这些代码片段之间的交互。例如:用户尝试使用已经被使用的用户名注册(电子邮件已经在使用中)。我需要一个测试,以便我可以拦截或看到验证是否工作,而不必访问数据库。在这些测试期间,我不想访问Mongo。这些应该是单元测试而不是集成测试。 :)
谢谢!
2个回答

11

最近我也遇到了同样的问题。

首先,我建议单独测试验证器。只需将它们移至单独的文件并导出您所拥有的验证函数即可。

这样可以轻松地将模型拆分成不同的文件,因为您可以在不同的模型之间共享这些验证器。

以下是单独测试验证器的示例:

// validators.js
exports.validatePresenceOf = function(value){ ... }
exports.validateEmail = function(value){ ... }

以下是一个示例测试(使用mocha+should):

// validators.tests.js
var validator = require('./validators')

// Example test
describe("validateEmail", function(){
   it("should return false when invalid email", function(){
       validator.validateEmail("asdsa").should.equal(false)
   })      
})

现在是更难的部分 :)

要测试您的模型是否有效而不需要访问数据库,可以直接在您的模型上调用一个验证函数。

以下是我目前的做法示例:

describe("validating user", function(){  
  it("should have errors when email is invalid", function(){
    var user = new User();
    user.email = "bad email!!" 
    user.validate(function(err){      
      err.errors.email.type.should.equal("Email is invalid")
    })
  })

  it("should have no errors when email is valid", function(){
    var user = new User();
    user.email = "test123@email.com"
    user.validate(function(err){
      assert.equal(err, null)
    })
  })
})   

验证回调会收到一个类似以下的错误对象:

{ message: 'Validation failed',
    name: 'ValidationError',
    errors: 
        { email: 
           { message: 'Validator "Email is invalid" failed for path email',
             name: 'ValidatorError',
             path: 'email',
             type: 'Email is invalid' 
           } 
        } 
}

我还不太熟悉nodeJS和mongoose,但这是我测试模型+验证器的方法,目前看来效果不错。


在最后几个测试中,当您调用user.validate()时:我正在使用grunt和Jasmine Node运行我的测试,并且我的断言从未被触发以使构建失败。我不得不为回调设置我的测试,以使断言正确运行。在我的情况下,使用jasmine-node,我在每个测试的末尾添加了jasmine.asyncSpecWait(),并在validate回调内部添加了jasmine.asyncSpecDone()。然后一切都很好。非常有帮助的答案! - Matt M.

2

您应该将validate()方法作为一个promise使用,并使用可以对异步内容进行断言的工具进行测试(例如:Chai as Promised)。

首先,需要引入一个promise库并切换到promise提供程序(例如Q):

mongoose.Promise = require('q').Promise;

之后,只需对承诺使用断言:

    it('should show errors on wrong email', function() {
        user = new UserModel({
            email: 'wrong email adress'
        });
        return expect(user.validate()).to.be.rejected;
    });

    it('should not show errors on valid email adress', function() {
        user = new UserModel({
            email: 'test@test.io'
        });
        return expect(user.validate()).to.be.fulfilled;
    });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接