如何使用 mongoose、mocha 和 chai 编写用于向 mongodb 插入和检索对象的单元测试?

Posted

技术标签:

【中文标题】如何使用 mongoose、mocha 和 chai 编写用于向 mongodb 插入和检索对象的单元测试?【英文标题】:How to write a Unit test for inserting and retrieving an object to mongodb using mongoose, mocha and chai? 【发布时间】:2016-10-28 05:17:31 【问题描述】:

我正在尝试编写一个单元测试,用于将文档插入(然后检索)到 mongodb。但是,我不断收到超时错误,这表明从未调用过 done。 (Mongod 正在运行,我可以看到正在插入的对象以及正在检索的对象,使用 console.log。)

我正在使用什么:

Node.js, ES6, 猫鼬, 摩卡, 柴

CheckbookEntry 是一些 Mongoose 调用的奇怪包装器,让我可以使用 Promise。

    describe('create and getOneById', () => 
    it('creates a new checkbookEntry, and retrieves it from the db', (done) => 
        var EXAMPLE_ENTRY = 
            type: 'debit',
            date: Date(),
            description: 'Example of a cb entry',
            account: 'PNC',
            amount: 239.33
        ;

        CheckbookEntry.create(EXAMPLE_ENTRY.type,
                              EXAMPLE_ENTRY.date,
                              EXAMPLE_ENTRY.description,
                              EXAMPLE_ENTRY.account,
                              EXAMPLE_ENTRY.amount)
                        .then(function(createdEntry)
                            return CheckbookEntry.getOneById(createdEntry._id);
                        )
                        .then(function(foundEntry)
                            expect(foundEntry).to.eql(EXAMPLE_ENTRY);
                            done();
                        , function(err)
                            assert.fail(err);
                            done();
                        );
    ).timeout(5000);

); // end describe create

关于如何使它工作的任何建议?

【问题讨论】:

【参考方案1】:

我只能猜测,但我认为问题可能是由这个引起的:

.then(function(foundEntry)
    expect(foundEntry).to.eql(EXAMPLE_ENTRY);
    done();
, function(err)
    assert.fail(err);
    done();
);

更具体地说,在履行/拒绝处理程序中使用断言而不继续承诺链。

如果断言抛出异常,done() 将永远不会被调用。并且根据正在使用的承诺实现,您甚至可能永远不会收到有关异常的通知。此外,onFulFilled 处理程序中引发的异常不会触发传递给同一 .then() 方法的onRejected 处理程序。

因为 Mocha supports promises out of the box,而不是使用 done 回调,返回你的承诺链:

return CheckbookEntry.create(...)
                     .then(...)
                     .then(..., ...);

这样,异常将被传播回 Mocha,由 Mocha 处理。

FWIW,猫鼬also supports promises out of the box。

【讨论】:

以上是关于如何使用 mongoose、mocha 和 chai 编写用于向 mongodb 插入和检索对象的单元测试?的主要内容,如果未能解决你的问题,请参考以下文章

单元/集成测试 Express REST API, mongoose, mocha, sinon, chai, supertest

“未检测到侦听器”验证错误 Mongoose 和 Mocha

node mongoose mocha:如何在我的测试中处理 Promise.reject

Mocha 抛出超时,但 Mongoose 将数据保存到 Promise 链中的数据库?

伊斯坦布尔封面报告对于使用 mocha 进行测试是错误的(使用 Mongoose)

在我的 node.js 应用程序中使用 mongodb 和 mongoose 在 Mocha 和 Chai 上运行测试后无法清除数据库