Skip to content

Mongo TestContainers

A package for the Ts.ED framework to help you test your code using the TestContainers library.

Note: This package does not depend on @tsed/platform-http. You can use it with any test framework.

✨ Features

  • 🚀 Spin up a MongoDB server using TestContainers for your tests
  • 🛑 Automatically stop the MongoDB server after your tests
  • 🔄 Reset the MongoDB server between test runs
  • 🏷️ Namespace support to isolate databases and avoid collisions between tests

📦 Installation

Install with your favorite package manager:

sh
npm install --save-dev @tsedio/testcontainers-mongo
sh
yarn add --dev @tsedio/testcontainers-mongo
sh
pnpm add --dev @tsedio/testcontainers-mongo
sh
bun add --dev @tsedio/testcontainers-mongo

TIP

See our documentation page for instructions on installing premium plugins.

⚙️ Configuration

Set up a global test lifecycle to manage the MongoDB container.

🧪 Vitest

Add a global setup file in your vitest.config.ts:

ts
import {defineConfig} from "vitest/config";

export default defineConfig({
  test: {
    globalSetup: [import.meta.resolve("@tsed/testcontainers-mongo/vitest/setup")]
  }
});

Add globalSetup and globalTeardown to your Jest config:

json
{
  "globalSetup": ["jest.setup.js"],
  "globalTeardown": ["jest.teardown.js"]
}

Example setup/teardown files:

ts
// jest.config.js
module.exports = {
  globalSetup: ["jest.setup.js"],
  globalTeardown: ["jest.teardown.js"]
};

// jest.setup.js
import {TestContainersMongo} from "@tsedio/testcontainers-mongo";

export default async () => {
  await TestContainersMongo.startContainer();
};

// jest.teardown.js
import {TestContainersMongo} from "@tsedio/testcontainers-mongo";

export default async () => {
  await TestContainersMongo.stopContainer();
};

🛠️ Basic Usage

ts
import {TestContainersMongo} from "@tsedio/testcontainers-mongo";

describe("MyTest", () => {
  beforeEach(() => {
    const connectionOptions = TestContainersMongo.getMongoOptions();
    console.log(connectionOptions);
  });

  afterEach(async () => {
    await TestContainersMongo.reset();
  });
});

🤝 Usage with @tsed/mongoose

🧩 Unit Test Example

ts
import {PlatformTest} from "@tsed/platform-http/testing";
import {Property, Required} from "@tsed/schema";
import {Model, MongooseModel, ObjectID, PostHook, PreHook, Unique} from "@tsed/mongoose";
import {TestContainersMongo} from "@tsedio/testcontainers-mongo";

@Model({schemaOptions: {timestamps: true}})
@PreHook("save", (user: UserModel, next: any) => {
  user.pre = "hello pre";
  next();
})
@PostHook("save", (user: UserModel, next: any) => {
  user.post = "hello post";
  next();
})
export class UserModel {
  @ObjectID("id")
  _id: string;

  @Property()
  @Required()
  @Unique()
  email: string;

  @Property()
  pre: string;

  @Property()
  post: string;
}

describe("UserModel", () => {
  beforeEach(() =>
    PlatformTest.create({
      mongoose: [TestContainersMongo.getMongoOptions()]
    })
  );
  afterEach(async () => {
    await TestContainersMongo.reset(); // reset the database
    await PlatformTest.reset();
  });

  it("should run pre and post hooks", async () => {
    const userModel = PlatformTest.get<MongooseModel<UserModel>>(UserModel);

    // GIVEN
    const user = new userModel({
      email: "test@test.fr"
    });

    // WHEN
    await user.save();

    // THEN
    expect(user.pre).toEqual("hello pre");
    expect(user.post).toEqual("hello post");
  });
});

🔗 Integration Test Example

Use PlatformTest.bootstrap and TestContainersMongo.getMongoOptions("default") to start the MongoDB server before your tests:

ts
beforeEach(() =>
  PlatformTest.bootstrap(Server, {
    mongoose: [TestContainersMongo.getMongoOptions()]
  })
);

🔄 Usage with MikroORM

Example using @tsedio/testcontainers-mongo with MikroORM:

ts
import {defineConfig} from "@mikro-orm/mongodb";
import {PlatformTest} from "@tsed/platform-http/testing";
import {TestContainersMongo} from "@tsedio/testcontainers-mongo";

beforeEach(async () => {
  const mongoSettings = TestContainersMongo.getMongoOptions();

  await PlatformTest.bootstrap(Server, {
    disableComponentScan: true,
    imports: [MikroOrmModule],
    mikroOrm: [
      defineConfig({
        clientUrl: mongoSettings.url,
        driverOptions: mongoSettings.connectionOptions,
        entities: [User],
        subscribers: [UnmanagedEventSubscriber1, new UnmanagedEventSubscriber2()]
      })
    ]
  });
});

💡 Tips

  • 🧹 Use TestContainersMongo.reset() to clear the database between tests.
  • 🏷️ Use TestContainersMongo.getMongoOptions(namespace, options) to generate MongoDB connection options:
    • namespace (string): isolates databases between tests.
    • options (object): corresponds to MongoClientOptions.
  • 🌐 You can define a global namespace using TestContainersMongo.setNamespace("my-namespace") if you don’t want to specify it on every call.

📚 Resources

Released under the MIT License.