【问题标题】:Duplicate data when testing with nodejs/mocha/mongoose使用 nodejs/mocha/mongoose 测试时重复数据
【发布时间】:2019-05-28 04:17:40
【问题描述】:

我正在使用 nodeJS/mocha/mongoose 运行异步测试,当我运行如下测试时,我的集合中不断收到重复的文档。

const assert = require('assert');
const User = require('../src/user');

describe('Duplicates records test', () => {

    beforeEach((done) => {
        let user = new User({ name: 'Bob'});
        user.save()
            .then(() => done()); 
    });

    it('Return users named Bob', (done) => {
        User.find({ name: 'Bob' })
            .then((users) => {
                console.log(users);
                done();
            });

    });
});

以下是我正在使用的模型:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const UserSchema = new Schema({
    name: String
});

const User = mongoose.model('user', UserSchema);

module.exports = User;

以下是运行测试的输出:

[ { _id: 5c918ca6d4b6eb4416312226, name: 'Bob', __v: 0 },
{ _id: 5c918ca6c2589d4415a4317a, name: 'Bob', __v: 0 } ]

1 passing (2s)

最后是 mongodb 的输出:

> db.users.find().pretty()
{ "_id" : ObjectId("5c918ca6d4b6eb4416312226"), "name" : "Bob", "__v" : 0 }
{ "_id" : ObjectId("5c918ca6c2589d4415a4317a"), "name" : "Bob", "__v" : 0 }

我的套件中有几个这样的测试,这似乎只有在我将记录保存在 beforeEach 语句中时才会发生。任何关于为什么会发生这种情况的见解将不胜感激。

【问题讨论】:

    标签: node.js


    【解决方案1】:

    这可能是因为您在启动下一个测试时没有逻辑删除之前保存的记录。

    为避免在使用 nodeJS/mocha/mongoose 进行测试时出现重复记录,您希望添加一些逻辑以至少在运行服务器进行测试时删除集合。

    您尚未共享您的 package.json 文件,但我建议您使用如下所示的脚本:

    "scripts": {
        "test": "NODE_ENV=test nodemon --exec 'mocha --recursive -R min'"
      },
    

    所以NODE_ENV 是一个环境变量,环境变量用于自定义行为或编码一些常量以在应用程序内部访问,您可以使用NODE_ENV 变量来指定服务器是否在开发、生产或其他环境中运行.

    因此,这将帮助您查看是否需要清空用户集合。

    为此,您可以引用变量process.env.NODE_ENV

    无论您在哪里与 Mongo 建立连接,您都希望像这样添加一个 if 语句:

    if (process.env.NODE_ENV !== "test") {
      mongoose.connect("mongodb://localhost/user", { useMongoClient: true });
    }
    

    所以你在这里说的是,在开发中运行时只需启动服务器并连接到数据库,但在测试中运行时,启动服务器,连接到数据库并删除集合,但这不是解决方案本身。

    我建议创建一个名为 user_test 的单独数据库,然后创建一个单独的帮助文件,其中包含用于连接到该数据库的逻辑。

    所以你将拥有两个独立的数据库。

    所以在上面的 if 语句中你说如果我在开发或生产环境中运行,如果它不等于 test,那么连接到这个数据库。如果我在测试中运行,请不要连接到此数据库。

    然后您将该测试帮助文件添加到将用于连接到 mongoose 的应用程序中。为什么要单独的测试帮助文件?因为这样可以更轻松地确保测试套件仅在与测试数据库建立连接后才启动。

    请记住,Mocha 和 Mongoose 并不能很好地搭配在一起,或者至少在我看来不是。

    这也很有帮助,因为您不必使用if 语句包装连接字符串来检查您是否在测试环境中。如果执行了测试帮助文件,那么是的,您在测试环境中,因此您不必明确说明。这个逻辑看起来像这样:

    const mongoose = require(‘mongoose’);
    
    before((done) => {
        mongoose.connect("mongodb://localhost/user_test”, { useMongoClient: true });
    });
    

    所以现在user_test 数据库可以整天被删除,并且不会发生任何坏事,您不会接触开发数据,因此以后您甚至可以自定义该开发数据库以包含一些您可能会用到的数据想要留下来。

    您还可以放置处理程序来查看连接状态,一旦连接打开,您就可以使用 done 回调,如下所示:

    const mongoose = require(‘mongoose’);
    
    before((done) => {
        mongoose.connect("mongodb://localhost/user_test”, { useMongoClient: true });
        mongoose.connection.once(‘open’, () => done())
    });
    

    如果出现错误,您可以像这样启动console.warn()

    const mongoose = require(‘mongoose’);
    
    before((done) => {
        mongoose.connect("mongodb://localhost/muber_test”, { useMongoClient: true });
        mongoose.connection.once(‘open’, () => done()).on(‘error’, (err) => {
            console.warn(‘Warning’, error);
        });
    });
    

    我喜欢这个解决方案,因为如果您将所有逻辑都定位在测试本身内部,有时 Mocha 会在连接到数据库之前执行测试,这意味着所有测试都会因此失败。

    差点忘了最重要的部分,丢了合集:

    const mongoose = require(‘mongoose’);
    
        before((done) => {
            mongoose.connect("mongodb://localhost/muber_test”, { useMongoClient: true });
            mongoose.connection.once(‘open’, () => done()).on(‘error’, (err) => {
                console.warn(‘Warning’, error);
            });
        });
    
    beforeEach((done) => {
        const { users } = mongoose.connection.collections;
        users.drop().then(() => done()).catch(() => done());
    });
    

    我们将catch() 放在done() 中的原因是它处理您的数据库第一次运行时,您还没有用户集合,这会引发错误,这就是我们添加的原因来处理这个案子。

    【讨论】:

      猜你喜欢
      • 2015-11-01
      • 2013-12-10
      • 1970-01-01
      • 2015-10-02
      • 1970-01-01
      • 2014-02-21
      • 2016-01-08
      • 2015-05-11
      • 1970-01-01
      相关资源
      最近更新 更多