我的 mongoose 模型包含一个字段,仅当另一个字段等于特定值(即它是有条件的)时才需要该字段。
在这个例子中,我有一个 item,它的 itemType 为“typeA”或“typeB”。字段 someField 仅对于“typeB”是必需的。
在我的测试中,直接针对模型进行测试时验证似乎有效。但是,验证不会在 Controller 中触发。
我的模型如下:
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var ItemSchema = new Schema({
name: {
type: String,
trim: true,
required: true
},
itemType: {
type: String,
enum: ['typeA', 'typeB'],
required: true
},
someField: String
});
ItemSchema
.path('someField')
.validate(function(value, respond) {
if (this.itemType === 'typeA') { return respond(true); }
return respond(validatePresenceOf(value));
}, 'someField cannot be blank for typeB');
function validatePresenceOf(value) {
return value && value.length;
}
module.exports = mongoose.model('Item', ItemSchema);
在我的模型单元测试中:
it('should fail when saving typeB without someField', function(done) {
var item = new Item({
name: 'test',
itemType: 'typeB'
});
item.save(function(err){
should.exist(err);
done();
});
});
上面的单元测试没有问题。但是,在测试 API 本身时,Mongoose 不会引发错误。如果无法保存, Controller 应该返回 500 错误:
exports.create = function(req, res) {
var item = new Item(req.body);
item.save(function(err, data) {
if (err) { return res.json(500, err); }
return res.json(200, data);
});
};
但是,下面的测试总是返回 200:
var request = require('supertest');
describe('with invalid fields', function() {
it('should respond with a 500 error', function(done) {
request(app)
.post('/api/item')
.send({
name: 'test',
itemType: 'typeB'
})
.expect(500)
.end(function(err, res) {
if (err) return done(err);
return done();
});
});
});
});
我不确定我做错了什么,当我在 Controller 中保存时似乎没有触发 Mongoose 验证。
最佳答案
这里的实现方式是错误的。您不验证“someField”,而是验证传递给“itemType”的值。原因是因为您没有为“someField”提供任何值,所以永远不会调用验证器,因为没有定义任何内容。
因此测试以相反的方式运行,并更正您的 validatePresenceOf()
函数:
itemSchema.path('itemType').validate(function(value) {
if ( value === 'typeA' )
return true;
console.log( validatePresenceOf(this.someField) );
return validatePresenceOf(this.someField);
}, 'someField cannot be blank for itemType: "typeB"');
function validatePresenceOf(value) {
if ( value != undefined )
return value && value.length
else
return false;
}
如果“itemType”设置为“typeB”并且“someField”根本没有值,则会正确抛出错误。
关于javascript - Mongoose 自定义验证在 Controller 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25671472/