Mocha, Supertest and Mongo Memory server, cannot setup hooks properly

Viewed 292

I have a Nodejs, Express server that uses Mongodb as the Database. I am trying to write some tests but I cannot get it configured properly. I need to create a mongoose connection for each block ( .test.ts file) once and then clean up the db for the other tests. Depending on how I approach this I get two different behaviours. But first my setup.

user.controller.test.ts

import { suite, test, expect } from "../utils/index";
import expressLoader from "@/loaders/express";
import { Logger } from "winston";
import express from "express";
import request from "supertest";
import { UserAccountModel } from "@/models/UserAccount";

import setup from "../setup";

setup();

import { app } from "@/server";
let loggerMock: Logger;

describe("POST /api/user/account/", function () {
  it("it should have status code 200 and create an user account", async function () {
    //GIVEN
    const userCreateRequest = {
      email: "test@gmail.com",
      userId: "testUserId",
    };

    //WHEN
    await request(app)
      .post("/api/user/account/")
      .send(userCreateRequest)
      .expect(200);

    //SHOULD
    const cnt: number = await UserAccountModel.count();
    expect(cnt).to.equal(1);
  });
});

And my other test post.repository.test.ts

import { suite, test, expect } from "../../utils/index";
import { PostModel } from "@/models/Posts/Post";
import PostRepository from "@/repositories/posts.repository";
import { PostType } from "@/interfaces/Posts";
import { Logger } from "winston";

@suite
class PostRepositoryTests {
  private loggerMock: Logger;
  private SUT: PostRepository = new PostRepository({});
  @test async "Should create two posts"() {
    //GIVEN
    const given = {
      id: "jobId123",
    };

    //WHEN
    await this.SUT.CreatePost(given);

    //SHOULD
    const cnt: number = await PostModel.count();
    expect(cnt).to.equal(1);
  }
}

And my setup

setup.ts

import { MongoMemoryServer } from "mongodb-memory-server";
import mongoose from "mongoose";

export = () => {
  let mongoServer: MongoMemoryServer;

  before(function () {
    console.log("Before");
    return MongoMemoryServer.create().then(function (mServer) {
      mongoServer = mServer;
      const mongoUri = mongoServer.getUri();
      return mongoose.connect(mongoUri);
    });
  });

  after(function () {
    console.log("After");
    return mongoose.disconnect().then(function () {
      return mongoServer.stop(true);
    });
  });
};

With the above setup I get

  1) "before all" hook in "{root}":
     MongooseError: Can't call `openUri()` on an active connection with different connection strings. Make sure you aren't calling `mongoose.connect()` multiple times. See: https://mongoosejs.com/docs/connections.html#multiple_connections

But if I don't import the setup.ts and I rename it to setup.test.ts, then it works but the data isn't cleared after each run so I actually have 10 new users created instead of 1. Every time I run it, it works and doesn't clear the data after it's finished.

Also I have a big issue where the tests hang and don't seem to finish. I am guessing that is because of the async, await in the tests or because of the hooks hanging.

What I want to happen is:

  1. Each test should have it's own setup, the mongo memory server should be clean every time.
  2. The tests should use async and await and not hang.
  3. Somehow export the setup from 1) as a utility function so that I can reuse it in my code
0 Answers
Related