摩卡——手表和猫鼬模型

Posted

技术标签:

【中文标题】摩卡——手表和猫鼬模型【英文标题】:mocha --watch and mongoose models 【发布时间】:2016-12-26 09:55:41 【问题描述】:

如果我让 mocha 监视更改,每次我保存文件时,mongoose 都会引发以下错误:

OverwriteModelError: 编译后无法覆盖Client 模型

我知道 mongoose 不允许定义模型两次,但我不知道如何使它与 mocha --watch 一起工作。

// client.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var clientSchema = new Schema(
    secret:  type: String, required: true, unique: true ,
    name: String,
    description: String,
    grant_types: [String],
    created_at:  type: Date, default: Date.now 
);

module.exports = mongoose.model('Client', clientSchema);

这是测试

// client-test.js
var chai = require('chai');
var chaiHttp = require('chai-http');
var mongoose = require('mongoose');

var server = require('../../app');
var Client = require('../../auth/models').Client;

var should = chai.should();

chai.use(chaiHttp);

describe('client endpoints', function() 
    after(function(done) 
        mongoose.connection.close();
        done();
    );

    it('should get a single client on /auth/client/clientId GET', function(done) 
        var clt = new Client(
            name: 'my app name',
            description: 'super usefull and nice app',
            grant_types: ['password', 'refresh_token']
        );

        clt.save(function(err) 
            chai.request(server)
                .get('/auth/client/' + clt._id.toString())
                .end(function(err, res) 
                    res.should.have.status(200);
                    res.should.be.json;
                    res.body.should.have.property('client_id');
                    res.body.should.not.have.property('secret');
                    res.body.should.have.property('name');
                    res.body.should.have.property('description');
                    done();
                );
        );
    );
);

【问题讨论】:

【参考方案1】:

我遇到了同样的问题。我的解决方案是检查模型是否已创建/编译,如果没有,则执行,否则只需检索模型。

使用mongoose.modelNames(),您可以获得模型名称的数组。然后使用 .indexOf 检查您要获取的模型是否在数组中。如果不是,则编译模型,例如:mongoose.model("User", UserSchema),但如果它已经定义(如 mocha --watch 的情况),只需检索模型(不要再次编译),您例如:mongoose.connection.model("User")

这是一个函数,它返回一个执行此检查逻辑的函数,它本身返回模型(通过编译或仅检索它)。

const mongoose = require("mongoose");
//returns a function which returns either a compiled model, or a precompiled model
//s is a String for the model name e.g. "User", and model is the mongoose Schema
function getModel(s, model) 
  return function() 
    return mongoose.modelNames().indexOf(s) === -1
      ? mongoose.model(s, model)
      : mongoose.connection.model(s);
  ;

module.exports = getModel;

这意味着你必须对你的模型有一点不同的要求,因为你可能会替换这样的东西:

module.exports = mongoose.model("User", UserSchema);

返回模型本身, 用这个:

module.exports = getModel("User", UserSchema);

它返回一个函数来返回模型,无论是通过编译还是仅仅检索它。这意味着当您需要“用户”模型时,您可能需要调用 getModel 返回的函数:

const UserModel = require("./models/UserModel")();

我希望这会有所帮助。

【讨论】:

【参考方案2】:

这是 George 提出的函数 getModel() 的更简单代码

function getModel(modelName, modelSchema) 
  return mongoose.models[modelName] // Check if the model exists
   ? mongoose.model(modelName) // If true, only retrieve it
   : mongoose.model(modelName, modelSchema) // If false, define it

有关如何定义和要求模型的详细说明,look here

希望这会有所帮助:)

【讨论】:

以上是关于摩卡——手表和猫鼬模型的主要内容,如果未能解决你的问题,请参考以下文章

如何在手表模式下进行任何摩卡测试之前运行全局设置脚本

打字稿和猫鼬:“文档”类型上不存在属性“x”

Angular 手表不会在值更改时触发

摩卡猫鼬错误

带有猫鼬调用的摩卡测试功能

GraphQL 和猫鼬有啥区别?