Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jest mockgoose - jest did not exit one second after the test run has completed

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?

like image 274
Miha Šušteršič Avatar asked Jun 29 '18 14:06

Miha Šušteršič


2 Answers

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());
like image 147
Estus Flask Avatar answered Oct 03 '22 07:10

Estus Flask


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."
          );
        });
      });
    });
  });
});
like image 40
Miha Šušteršič Avatar answered Oct 03 '22 08:10

Miha Šušteršič