4

I have the following model:

var mongoose = require("mongoose");
var categories = require("../constants/categories");

var transactionSchema = mongoose.Schema({
  category: {
    type: String,
    required: [true, "Category is required."],
    validate: {
      validator: function(v) {
        return (
          categories
            .map(function(category) {
              return category.name;
            })
            .indexOf(v) > -1
        );
      },
      message: "{VALUE} is not a valid category."
    }
  },
  amount: { type: Number, required: [true, "Amount is required"] },
  comment: String,
  tags: Array,
  currency: String
});

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

And a unit test for this model:

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();
  });

  test("category should match one of the predefined categories", function() {
    expect.assertions(1);
    return mockgoose.prepareStorage().then(function() {
      mongoose.connect("mongodb://foobar/baz");
      return mongoose.connection.on("connected", function() {
        var mockTransaction = new Transaction({
          category: "dsawdsfawfsaf",
          amount: 25,
          comment: "Gas money, Petrol.",
          tags: ["Gas", "Car", "Transport"],
          currency: "EUR"
        });
        return mockTransaction.save(function(err, savedTransaction) {
          expect(err.errors.category.properties.message).toBe(
            "{VALUE} is not a valid category."
          );
        });
      });
    });
  });
});

Running jest --detectOpenHandles prints out the following:

Jest has detected the following 1 open handle potentially keeping Jest from exiting:

● PROMISE

  25 | });
  26 | 
> 27 | var Transaction = mongoose.model("Transaction", transactionSchema);
     |                            ^
  28 | module.exports = Transaction;
  29 | 

  at Function.init (node_modules/mongoose/lib/model.js:970:16)
  at Mongoose.Object.<anonymous>.Mongoose.model (node_modules/mongoose/lib/index.js:396:11)
  at Object.<anonymous> (models/transaction.js:27:28)
  at Object.<anonymous> (models/transaction.test.js:3:19)

Why does this happen and how do I fix it?

skyboyer
  • 22,209
  • 7
  • 57
  • 64
Miha Šušteršič
  • 9,742
  • 25
  • 92
  • 163
  • Have u fixed this? – Manuel Sánchez Jul 02 '18 at 15:01
  • 1
    @ManuelDavidSánchezSuero yes, the problem is that if you try to kill connections `afterAll` but make them separately for every test, the reference to the connection is lost, and some of the remain open. So the solution is to either make the setup in the `beforeAll` function, or close the connection in `afterEach` – Miha Šušteršič Jul 02 '18 at 18:51
  • 1
    I would recommend you to mark the question as resolved and add a better explanation for this. – Manuel Sánchez Jul 03 '18 at 15:24
  • 1
    I have a similar problem to this but can't fix it the way you describe above. I can fix it by using the skipInit parameter in mongoose.model and setting it to true, however I think this then breaks the behaviour of the schema, as in the live database I cannot add two items with the same email address, but on the in-memory test database this seems to be allowed – Zief Aug 07 '18 at 17:11

0 Answers0