简体   繁体   中英

Jest Unit Testing Returning “MongoError: topology was destroyed”

I am trying to use Jest for running unit tests with my Node.js app.

I have created a setup script to close the mongoose connection by calling the afterAll() function.

The issue I am having is that after running a unit test, the error MongoError: topology was destroyed is displayed in the console.

I believe this to be an issue with how I'm implementing asynchronous functions... maybe I'm not waiting long enough to return a promise? See the code below.

Jest Config (package.json):

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

Setup Script (./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;
    });
});

Unit Test (./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();
        });
    });
});

Response (npm test):

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
...

When you first connect to mongo, you have a topology. In your test hooks, you drop the database (which blows out the topology). You then are trying to use the same connection in your second test to connect to database that isn't there anymore.

I think your second test is giving you a false positive on what the error really is. I imagine if you comment out the beforeEach block, you'll get a different outcome for the test.

If you're looking to clear out a collection before every test, you should use mongoose's dropCollection method in your beforeEach hook. I think the collection should be auto created by mongoose on your next test. If the collection isn't re-created, you can add mongoose's createCollection method in the same hook.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM