简体   繁体   English

Mongoose自定义验证无法在控制器中工作

[英]Mongoose custom validation not working in controller

My mongoose model contains a field that is only required if another field equals a specific value (ie it is conditional). 我的猫鼬模型包含一个字段,只有当另一个字段等于特定值时才需要该字段(即它是有条件的)。

In this example, I have an item which has an itemType of 'typeA' or 'typeB'. 在这个例子中,我有具有“的typeA”或“的TypeB”的ITEMTYPE项目 The field someField is only required for 'typeB'. 只有'typeB'才需要字段someField

In my tests, the validation seems to work when testing against the model directly. 在我的测试中,验证似乎在直接测试模型时起作用。 However, the validation is not trigger in the controller. 但是,验证不会在控制器中触发。

My model is as follows: 我的模型如下:

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);

In my unit test for the model: 在我的模型单元测试中:

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();
  });

});

The above unit test works with no problem. 上面的单元测试没有问题。 However, when testing the API itself, Mongoose does not raise an error. 但是,在测试API本身时,Mongoose不会引发错误。 The controller is supposed to return a 500 error if it cannot save: 如果控制器无法保存,则应该返回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);
  });
};

However, the following test always returns a 200: 但是,以下测试始终返回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();
        });
      });
  });
});

I'm not sure what I'm doing wrong, it seems the Mongoose validation is not being triggered when I save in the controller. 我不确定我做错了什么,当我保存在控制器中时,似乎没有触发Mongoose验证。

The implementation is the wrong way around here. 这里的实施是错误的。 You don't validate on 'someField' but on the value that is passed to 'itemType'. 您不验证'someField',而是验证传递给'itemType'的值。 The reason why is since you have not supplied any value for 'someField' then the validator is never called since there is nothing defined. 原因是因为你没有为'someField'提供任何值,所以从未调用验证器,因为没有定义任何东西。

So the test runs the other way around, as well as correcting your validatePresenceOf() function: 因此,测试以相反的方式运行,以及更正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;
}

That will throw an error correctly is 'itemType' is set to 'typeB' and the 'someField' has no value at all. 如果'itemType'设置为'typeB'并且'someField'根本没有值,则会正确抛出错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM