javascript - Mongoose 自定义验证在 Controller 中不起作用

标签 javascript node.js mongodb mongoose

我的 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/

相关文章:

javascript - 正则表达式捕获引号后跟非标点字符

node.js - 使用 nginx 作为反向代理时,缓存静态文件不起作用

javascript - 使用 NestJS 授予 Auth0 授权码

node.js - 如何确定包含多个流的流中文件的结尾? ( Node )

javascript - 蒙哥错误: topology was destroyed sailsjs

JavaScript substr(),获取字符串中间的字符

javascript - 我想用 Javascript API V3 创建一个 donut (里面的空白空间像一个洞)

javascript - window.getSelection() 与 emoji-mart(选择器组件)的问题

MongoDB:通过不存在的字段查找文档?

javascript - Meteor:如何通过 session 变量过滤数据