Skip to content

Commit

Permalink
MongoDB testing recipe (#1357)
Browse files Browse the repository at this point in the history
  • Loading branch information
CImrie authored and sindresorhus committed May 6, 2017
1 parent 1d04153 commit 970872c
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 0 deletions.
105 changes: 105 additions & 0 deletions docs/recipes/isolating-mongodb-integration-tests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Isolated MongoDB integration tests

This recipe outlines how to run disposable MongoDB databases in your AVA tests with per-test isolation. This uses `mongomem` which is available on [npm](https://www.npmjs.com/package/mongomem).

`mongomem` is a package that allows you to quickly run a temporary MongoDB server locally. It uses temporary file storage which is destroyed when the server stops.


## Install MongoDB in-memory Server (MongoMem)

In the root directory of your application, run:

```console
$ npm install --save-dev mongomem
```


## Using MongoMem

In your test file, import the module, and run the server.

**Make sure to run the server at the start of your file, outside of any test cases.**

```js
import test from 'ava';
import {MongoDBServer} from 'mongomem';

test.before('start mongodb server', async t => {
await MongoDBServer.start();
})

test('some feature', async t => {
const connectionString = await MongoDBServer.getConnectionString();

// connectionString === 'mongodb://localhost:27017/3411fd12-b5d6-4860-854c-5bbdb011cb93'
// Use `connectionString` to connect to the database with a client of your choice. See below for usage with Mongoose.
});
```


## Cleaning Up

After you have run your tests, you should include a `test.after.always()` method to clean up the MongoDB server. This will remove any temporary files the server used while running.

This is normally cleaned up by your operating system but it is good practise to do it manually to avoid OS-specific issues.

```js
test.after.always('cleanup', t => {
MongoDBServer.tearDown(); // This will clean up temporary file storage
});
```


## Debugging

If the server does not seem to start, you can set the following option before you call `MongoDBServer.start()`:
`MongoDBServer.debug = true;`

This will allow the MongoDB server to print connection or file permission errors when it's starting. It checks and picks an available port to run the server on, so errors are likely to be related to file permissions.


## Extra: Setup and Use in Mongoose (MongoDB ODM)

Mongoose is a robust Object-Document-Mapper (ODM) for MongoDB. Refer to [Mongoose ODM v4.9.4](http://mongoosejs.com) for full guides and documentation to get started with Mongoose.

### Import Mongoose

```js
// `myTestCase.test.js` - (your test case file!)
import mongoose from 'mongoose';
```

`mongoose` in this case is a single instance of the Mongoose ODM and is globally available. This is great for your app as it maintains a single access point to your database, but less great for isolated testing.

You should isolate Mongoose instances between your tests, so that the order of test execution is never depended on. This can be done with a little bit of work.

### Isolate Mongoose Instance

You can easily request a new instance of Mongoose. First, call `new mongoose.Mongoose()` to get the new instance, and then call `connect` with a database connection string provided by the `mongomem` package.

**You will have to manually copy models from the global instance to your new instance.**

```js
import mongoose from 'mongoose';
import {MongoDBServer} from 'mongomem';

test.before('start mongodb', async t => {
await MongoDBServer.start();
});

test.beforeEach(async t => {
const db = new mongoose.Mongoose();
await db.connect(await MongoDBServer.getConnectionString());

for (const name of mongoose.modelNames()) {
db.model(name, mongoose.model(name).schema);
}

t.context.db = db;
});

test('my mongoose model integration test', async t => {
const {db} = t.context;
// Now use the isolated DB instance in your test
});
```
1 change: 1 addition & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -1163,6 +1163,7 @@ It's the [Andromeda galaxy](https://simple.wikipedia.org/wiki/Andromeda_galaxy).
- [Debugging tests with Chrome DevTools](docs/recipes/debugging-with-chrome-devtools.md)
- [Debugging tests with WebStorm](docs/recipes/debugging-with-webstorm.md)
- [Precompiling source files with webpack](docs/recipes/precompiling-with-webpack.md)
- [Isolated MongoDB integration tests](docs/recipes/isolating-mongodb-integration-tests.md)

## Support

Expand Down

0 comments on commit 970872c

Please sign in to comment.