【问题标题】:Mongoose custom validation not working in controllerMongoose 自定义验证在控制器中不起作用
【发布时间】:2017-06-27 21:18:59
【问题描述】:

我的猫鼬模型包含一个字段,仅当另一个字段等于特定值时才需要(即它是有条件的)。

在本例中,我有一个 item,它的 itemType 为“typeA”或“typeB”。 someField 字段仅对“typeB”是必需的。

在我的测试中,直接针对模型进行测试时,验证似乎有效。但是,验证不会在控制器中触发。

我的模型如下:

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 不会引发错误。如果无法保存,控制器应该返回 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();
        });
      });
  });
});

我不确定我做错了什么,当我在控制器中保存时似乎没有触发 Mongoose 验证。

【问题讨论】:

    标签: javascript node.js mongodb mongoose


    【解决方案1】:

    这里的实现方式是错误的。您不验证“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' 没有任何值,则会正确抛出错误。

    【讨论】:

    • 谢谢尼尔,非常有道理:)
    猜你喜欢
    • 2015-10-28
    • 2021-01-25
    • 1970-01-01
    • 1970-01-01
    • 2017-09-01
    • 2013-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多