Skip to content

Commit

Permalink
fix(testcontainers-mongo): update readme package and add documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Romakita committed Aug 25, 2024
1 parent bd781f1 commit 9230a2a
Show file tree
Hide file tree
Showing 7 changed files with 282 additions and 169 deletions.
3 changes: 3 additions & 0 deletions docs/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ frameworks:
- title: Pulse
href: /tutorials/pulse.html
src: /pulse.png
- title: TestContainers
href: /tutorials/mongoose.html#testing
src: https://avatars.githubusercontent.com/u/13393021?s=200&v=4
---

::: slot hero-brand
Expand Down
179 changes: 106 additions & 73 deletions docs/tutorials/mongoose.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,40 @@ Currently, [`@tsed/mongoose`](https://www.npmjs.com/package/@tsed/mongoose) allo

Before using the `@tsed/mongoose` package, we need to install the [mongoose](https://www.npmjs.com/package/mongoose) module.

```bash
npm install --save mongoose
npm install --save @tsed/mongoose
npm install --save-dev @tsed/testing-mongoose
<Tabs class="-code">
<Tab label="npm">

```sh [npm]
npm install --save mongoose @tsed/mongoose
npm install --save-dev @tsed/testcontainers-mongo
```

::: warning
Since mongoose v5.11.0, the module expose his own file definition and can broke your build!
To solve it, install @tsed/mongoose v6.14.1 and remove the `@types/mongoose` dependencies.
:::
</Tab>
<Tab label="yarn">

```sh [yarn]
yarn add mongoose @tsed/mongoose
yarn add -D @tsed/testcontainers-mongo
```

</Tab>
<Tab label="pnpm">

```sh [pnpm]
pnpm add mongoose @tsed/mongoose
pnpm add -D @tsed/testcontainers-mongo
```

</Tab>
<Tab label="bun">

```sh [bun]
bun add mongoose @tsed/mongoose
bun add -D @tsed/testcontainers-mongo
```

</Tab>
</Tabs>

Then import `@tsed/mongoose` in your [Configuration](/docs/configuration.md):

Expand Down Expand Up @@ -319,92 +343,84 @@ export class MyRepository {

## Testing

The package [`@tsed/testing-mongoose`](https://www.npmjs.com/package/@tsed/testing-mongoose) allows you to test your server with a memory database.
The [`@tsed/testcontainers-mongo`](https://www.npmjs.com/package/@tsed/testcontainers-mongo) package allows you to test your code using the [TestContainers](https://node.testcontainers.org/) library.

::: tip
This package uses the amazing [mongodb-memory-server](https://www.npmjs.com/package/mongodb-memory-server) to mock the mongo database.
:::
### Configuration

### Testing API

This example shows you how you can test your Rest API with superagent and a mocked Mongo database:
To use the `@tsed/testcontainers-mongo` package, you need to install the package:

<Tabs class="-code">
<Tab label="Jest">
<Tab label="npm">

<<< @/tutorials/snippets/mongoose/testing-api.jest.ts
```sh [npm]
npm install --save-dev @tsed/testcontainers-mongo
```

</Tab>
<Tab label="Mocha">
<Tab label="yarn">

<<< @/tutorials/snippets/mongoose/testing-api.mocha.ts
```sh [yarn]
yarn add --dev @tsed/testcontainers-mongo
```

</Tab>
</Tabs>
<Tab label="pnpm">

::: tip
To increase mocha timeout from 2000ms to 10000ms use option `--timeout 10000`.
:::

### Testing API with ReplicaSet
```sh [pnpm]
pnpm add --dev @tsed/testcontainers-mongo
```

A [ReplicaSet](https://github.com/nodkz/mongodb-memory-server#replica-set-start) can be easily started with:
</Tab>
<Tab label="bun">

```typescript
import {PlatformTest} from "@tsed/common";
import {PlatformExpress} from "@tsed/platform-express";
import {TestMongooseContext} from "@tsed/testing-mongoose";
import {expect} from "chai";
import * as SuperTest from "supertest";
import {Server} from "../Server";

describe("Rest", () => {
// bootstrap your Server to load all endpoints before run your test
let request: SuperTest.Agent;

before(
TestMongooseContext.bootstrap(Server, {
platform: PlatformExpress,
mongod: {
replicaSet: true
}
})
); // Create a server with mocked database
before((done) => {
request = SuperTest(PlatformTest.callback());
done();
});

after(TestMongooseContext.reset); // reset database and injector

describe("GET /rest/calendars", () => {
it("should do something", async () => {
const response = await request.get("/rest/calendars").expect(200);

expect(response.body).to.be.an("array");
});
});
});
```sh [bun]
bun add --dev @tsed/testcontainers-mongo
```

### Jest additional setup
</Tab>
</Tabs>

Then add or update your jest or vitest configuration file to add a global setup file:

Add a script to close connection after all unit test. In your jest configuration file add the following line:
<Tabs class="-code">
<Tab label="Jest">

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

And create the script with the following content:
// jest.setup.js
const {TestContainersMongo} = require("@tsed/testcontainers-mongo");
module.exports = async () => {
await TestContainersMongo.startMongoServer();
};

```js
// jest.teardown.js
const {TestContainersMongo} = require("@tsed/testcontainers-mongo");
module.exports = async () => {
(await global.__MONGOD__) && global.__MONGOD__.stop();
await TestContainersMongo.stopMongoServer();
};
```

</Tab>
<Tab label="Vitest">

```ts [Vitest]
import {defineConfig} from "vitest/config";

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

</Tab>
</Tabs>

### Testing Model

This example shows you how can test the model:
Expand All @@ -415,13 +431,30 @@ This example shows you how can test the model:
<<< @/tutorials/snippets/mongoose/testing-model.jest.ts

</Tab>
<Tab label="Mocha">
<Tab label="Vitest">

<<< @/tutorials/snippets/mongoose/testing-model.mocha.ts
<<< @/tutorials/snippets/mongoose/testing-model.vitest.ts

</Tab>
</Tabs>

### Testing API

This example shows you how you can test your Rest API with superagent and a mocked Mongo database:

<Tabs class="-code">
<Tab label="Jest">

<<< @/tutorials/snippets/mongoose/testing-api.jest.ts

</Tab>
<Tab label="Vitest">

<<< @/tutorials/snippets/mongoose/testing-api.jest.ts

</Tab>
</Tabs>

## Author

<GithubContributors :users="['Romakita']"/>
Expand Down
14 changes: 4 additions & 10 deletions docs/tutorials/snippets/mongoose/testing-api.jest.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
import {PlatformTest} from "@tsed/common";
import {TestMongooseContext} from "@tsed/testing-mongoose";
import {TestContainersMongo} from "@tsed/testcontainers-mongo";
import * as SuperTest from "supertest";
import {Server} from "../Server";

describe("Rest", () => {
// bootstrap your Server to load all endpoints before run your test
let request: SuperTest.Agent;

before(TestMongooseContext.bootstrap(Server)); // Create a server with mocked database
before(() => {
request = SuperTest(PlatformTest.callback());
});

after(TestMongooseContext.reset); // reset database and injector
beforeAll(TestContainersMongo.bootstrap(Server)); // Create a server with mocked database
afterAll(() => TestContainersMongo.reset()); // reset database and injector

describe("GET /rest/calendars", () => {
it("should do something", async () => {
const request = SuperTest(PlatformTest.callback());
const response = await request.get("/rest/calendars").expect(200);

expect(typeof response.body).toEqual("array");
Expand Down
18 changes: 18 additions & 0 deletions docs/tutorials/snippets/mongoose/testing-api.vitest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {PlatformTest} from "@tsed/common";
import {TestContainersMongo} from "@tsed/testcontainers-mongo";
import * as SuperTest from "supertest";
import {Server} from "../Server";

describe("Rest", () => {
beforeAll(TestContainersMongo.bootstrap(Server)); // Create a server with mocked database
afterAll(() => TestContainersMongo.reset()); // reset database and injector

describe("GET /rest/calendars", () => {
it("should do something", async () => {
const request = SuperTest(PlatformTest.callback());
const response = await request.get("/rest/calendars").expect(200);

expect(typeof response.body).toEqual("array");
});
});
});
9 changes: 5 additions & 4 deletions docs/tutorials/snippets/mongoose/testing-model.jest.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {PlatformTest, Property, Required} from "@tsed/common";
import {PlatformTest} from "@tsed/common";
import {Property, Required} from "@tsed/schema";
import {Model, MongooseModel, ObjectID, PostHook, PreHook, Unique} from "@tsed/mongoose";
import {TestMongooseContext} from "@tsed/testing-mongoose";
import {TestContainersMongo} from "@tsed/testcontainers-mongo";

@Model({schemaOptions: {timestamps: true}})
@PreHook("save", (user: UserModel, next: any) => {
Expand Down Expand Up @@ -30,8 +31,8 @@ export class UserModel {
}

describe("UserModel", () => {
beforeEach(TestMongooseContext.create);
afterEach(TestMongooseContext.reset);
beforeEach(() => TestContainersMongo.create());
afterEach(() => TestContainersMongo.reset("users")); // clean users collection after each test

it("should run pre and post hook", async () => {
const userModel = PlatformTest.get<MongooseModel<UserModel>>(UserModel);
Expand Down
52 changes: 52 additions & 0 deletions docs/tutorials/snippets/mongoose/testing-model.vitest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import {PlatformTest} from "@tsed/common";
import {Property, Required} from "@tsed/schema";
import {Model, MongooseModel, ObjectID, PostHook, PreHook, Unique} from "@tsed/mongoose";
import {TestContainersMongo} from "@tsed/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(() => TestContainersMongo.create());
afterEach(() => TestContainersMongo.reset("users")); // clean users collection after each test

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

// GIVEN
const user = new userModel({
email: "[email protected]"
});

// WHEN
await user.save();

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

0 comments on commit 9230a2a

Please sign in to comment.