2012-02-10 88 views
5

有谁知道如何测试Mongoose验证?测试MongooseJs验证

实施例,我有以下模式(作为例子):

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._-][email protected][a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/.test(val); 
} 

我要测试的验证。最终结果是,我希望能够测试验证,并根据这些事情发生,然后我可以编写其他测试来测试这些代码片段之间的交互。例如:用户尝试使用与使用相同的用户名注册(电子邮件已在使用中)。我需要一个测试,我可以实际拦截或看到验证正在工作而没有击中数据库。在这些测试中,我不想打蒙戈。这些应该是UNIT测试而不是集成测试。 :)

谢谢!

回答

9

我最近有同样的问题。

首先我会推荐自己测试验证器。只需将它们移动到单独的文件并导出您拥有的验证功能即可。

这很容易让您的模型被分割成单独的文件,因为您可以在不同的模型中共享这些验证器。

这里是对自己的测试验证器的一个示例:

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

下面是该(使用摩卡+应该)的样品测试:

// 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 = "[email protected]" 
    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和猫鼬,但这是我如何测试我的模型+验证器,它似乎目前工作得很好。

+0

在过去的几您呼叫用户的测试。validate():我正在使用grunt和Jasmine Node运行我的测试,并且我的断言从未被命中以失败构建。我必须设置回调的测试才能使断言正常运行。在我的情况下,使用jasmine-node,我在验证回调中添加了一个jasmine.asyncSpecWait()到每个测试的结尾和一个jasmine.asyncSpecDone()。然后一切都很好。非常有用的答案! – 2014-03-17 17:30:07

2

您应该使用validate()方法作为承诺,并使用针对异步内容声明的工具(例如:Chai as Promised)对其进行测试。

首先,需要一个承诺库,并转出的承诺提供商(例如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: '[email protected]' 
     }); 
     return expect(user.validate()).to.be.fulfilled; 
    });