开玩笑单元测试返回“MongoError:拓扑被破坏”

Posted

技术标签:

【中文标题】开玩笑单元测试返回“MongoError:拓扑被破坏”【英文标题】:Jest Unit Testing Returning "MongoError: topology was destroyed" 【发布时间】:2019-11-14 19:08:27 【问题描述】:

我正在尝试使用 Jest 对我的 Node.js 应用程序运行单元测试。

我创建了一个设置脚本,通过调用afterAll() 函数来关闭猫鼬连接。

我遇到的问题是,运行单元测试后,控制台中显示错误MongoError: topology was destroyed

我认为这是我如何实现异步函数的问题......也许我没有等待足够长的时间来返回一个承诺?请参阅下面的代码。

Jest 配置(package.json):

"jest": 
    "testEnvironment": "node",
    "setupFilesAfterEnv": [
      "./tests/setup.js"
    ]
  ,

设置脚本 (./tests/setup.js):

const mongoose = require("mongoose");
const config = require("../config/config");

beforeAll(async function() 
    // Define database credentials.
    let dbUser = encodeURIComponent(config.db.username);
    let dbPass = encodeURIComponent(config.db.password);
    let dbDatabase = encodeURIComponent(config.db.database);
    let mongoUri = `mongodb://$dbUser:$dbPass@$config.db.host:$config.db.port/$dbDatabase`;

    // Connect to the database.
    await mongoose.connect(mongoUri,  useNewUrlParser: true , function(err) 
        if(err) throw err;
    );
);

beforeEach(async function() 
    // Clear the database.
    await mongoose.connection.dropDatabase(function(err) 
        if(err) throw err;
    );
);

afterAll(async function() 
    // Terminate the database connection.
    mongoose.connection.close(function(err) 
        if(err) throw err;
    );
);

单元测试(./tests/models/api_session.test.js):

const ApiSession = require("../../app/models/api_session");

describe("new session", function() 
    test("valid session", function(done) 
        let apiSession = new ApiSession( authCode: "12345" );
        apiSession.save(function(err, result) 
            if(err) done(err);

            expect(result.authCode).toBe("12345");
            done();
        );
    );

    test("empty session", function(done) 
        let apiSession = new ApiSession();
        apiSession.save(function(err) 
            expect(err.name).toBe("ValidationError");
            done();
        );
    );
);

响应(np​​m 测试):

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        0.852s, estimated 1s
Ran all test suites.

MongoError: topology was destroyed
...

【问题讨论】:

【参考方案1】:

当你第一次连接到 mongo 时,你有一个拓扑。在您的测试挂钩中,您删除了数据库(这会破坏拓扑)。然后,您尝试在第二个测试中使用相同的连接来连接到不再存在的数据库。

我认为您的第二次测试对错误真正是什么给出了误报。我想如果你注释掉 beforeEach 块,你会得到不同的测试结果。

如果你想在每次测试之前清除一个集合,你应该在你的 beforeEach 钩子中使用 mongoose 的 dropCollection 方法。我认为集合应该由猫鼬在您的下一次测试中自动创建。如果集合没有重新创建,您可以在同一个钩子中添加 mongoose 的 createCollection 方法。

【讨论】:

这是完全合理的。我假设删除数据库将被重建 - 但这在拓扑中间时会失败是有道理的。我已将代码解决方案添加到您的答案中。谢谢!

以上是关于开玩笑单元测试返回“MongoError:拓扑被破坏”的主要内容,如果未能解决你的问题,请参考以下文章

开玩笑单元测试检查唯一值

调度程序没有在开玩笑的单元测试中注册回调

在开玩笑的单元测试角度显示正确的错误

开玩笑的带有 expo sqlite 调用的单元测试类

Dispatcher 没有在开玩笑的单元测试中注册回调

开玩笑的单元测试不会等待 axios 响应