jest mockgoose - jest did not exit one second afte

2019-02-13 22:11发布

I have a mongoose model:

var mongoose = require("mongoose");

var transactionSchema = mongoose.Schema({
  category: { type: String, required: [true, "Category is required."] },
  amount: Number,
  comment: String,
  tags: Array,
  currency: String
});

var Transaction = mongoose.model("Transaction", transactionSchema);

module.exports = Transaction;

And a simple unit test using mockgoose and jest:

var { Mockgoose } = require("mockgoose");
var mongoose = require("mongoose");
var Transaction = require("./transaction");

var mockgoose = new Mockgoose(mongoose);

describe("transaction", function() {
  afterEach(function() {
    mockgoose.helper.reset().then(() => {
      done();
    });
  });

  it("category is required", function() {
    mockgoose.prepareStorage().then(() => {
      mongoose.connect("mongodb://foobar/baz");
      mongoose.connection.on("connected", () => {
        var mockTransaction = new Transaction({
          category: "Transportation",
          amount: 25,
          comment: "Gas money, Petrol.",
          tags: ["Gas", "Car", "Transport"],
          currency: "EUR"
        });
        mockTransaction.save(function(err, savedTransaction) {
          if (err) return console.error(err);
          expect(savedTransaction).toEqual(mockTransaction);
        });
      });
    });
  });
});

Now when I run my tests, I get these two warnings:

(node:2199) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): ReferenceError: done is not defined (node:2199) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Then the unit test passes, and then I get this error message:

Jest did not exit one second after the test run has completed.

This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with --detectOpenHandles to troubleshoot this issue.

How do I terminate the test once I get to the correct result?

2条回答
祖国的老花朵
2楼-- · 2019-02-13 22:57

There were a few things wrong with the initial test.

The first one was pointed out by @estus, promises need to be returned when testing with jest. The second issue that caused the error in the title of the question was caused by not closing the db connection properly after the tests.

This is the final code where everything runs as expected:

var { Mockgoose } = require("mockgoose");
var mongoose = require("mongoose");
var Transaction = require("./transaction");

var mockgoose = new Mockgoose(mongoose);

describe("transaction", function() {
  afterEach(function() {
    return mockgoose.helper.reset();
  });

  afterAll(function() {
    const { connections } = mongoose;
    const { childProcess } = mockgoose.mongodHelper.mongoBin;
    // kill mongod
    childProcess.kill();
    // close all connections
    for (const con of connections) {
      return con.close();
    }
    return mongoose.disconnect();
  });

  it("category is required", function() {
    expect.assertions(1);
    return mockgoose.prepareStorage().then(function() {
      mongoose.connect("mongodb://foobar/baz");
      return mongoose.connection.on("connected", function() {
        var mockTransaction = new Transaction({
          amount: 25,
          comment: "Gas money, Petrol.",
          tags: ["Gas", "Car", "Transport"],
          currency: "EUR"
        });
        return mockTransaction.save(function(err, savedTransaction) {
          console.log(err.errors.category.properties.message);
          expect(err.errors.category.properties.message).toBe(
            "Category is required."
          );
        });
      });
    });
  });
});
查看更多
老娘就宠你
3楼-- · 2019-02-13 23:10

The error means exactly what it says, done wasn't defined but it's used. And it isn't needed in case promises are used. Jest supports promises, a promise should be returned from a block in order to be properly handled:

afterEach(() => mockgoose.helper.reset());

If there's a problem with open handles as in this question, Mongoose can be explicitly disconnected with:

afterAll(() => mongoose.disconnect());
查看更多
登录 后发表回答