|
| 1 | +# mongodb-memory-server |
| 2 | + |
| 3 | +[](https://www.npmjs.com/package/mongodb-memory-server) |
| 4 | +[](http://www.npmtrends.com/mongodb-memory-server) |
| 5 | +[](https://travis-ci.org/nodkz/mongodb-memory-server) |
| 6 | +[](http://commitizen.github.io/cz-cli/) |
| 7 | + |
| 8 | +This package spins up a actual/real MongoDB Server programmatically from node for testing or mocking during development. By default it holds the data in memory. Fresh spinned up `mongod` process takes about 7Mb of memory. The server will allow you to connect your favorite ODM or client library to the MongoDB Server and run integration tests isolated from each other. You can start up several mongod simultaneously, it automatically discovers free ports. |
| 9 | + |
| 10 | +This package use [mongodb-prebuilt](https://github.com/winfinit/mongodb-prebuilt) which on first start downloads the latest MongoDB binaries and save it to `~/.mongodb-prebuilt` folder. So first run may take a time. All further runs will use downloaded version. |
| 11 | + |
| 12 | +## Installation |
| 13 | +``` |
| 14 | +yarn add mongodb-memory-server --dev |
| 15 | +OR |
| 16 | +npm install mongodb-memory-server --save-dev |
| 17 | +``` |
| 18 | + |
| 19 | +## Usage |
| 20 | + |
| 21 | +### Simple server start: |
| 22 | +```js |
| 23 | +import MongodbMemoryServer from 'mongodb-memory-server'; |
| 24 | + |
| 25 | +const mongod = new MongoMemoryServer(); |
| 26 | + |
| 27 | +const uri = await mongod.getConnectionString(); |
| 28 | +const port = await mongod.getPort(); |
| 29 | +const dbPath = await mongod.getDbPath(); |
| 30 | + |
| 31 | +mongod.stop(); |
| 32 | +``` |
| 33 | + |
| 34 | +### Provide connection string to mongoose |
| 35 | +```js |
| 36 | +import mongoose from 'mongoose'; |
| 37 | +import MongodbMemoryServer from 'mongodb-memory-server'; |
| 38 | + |
| 39 | +const mongoServer = new MongoMemoryServer(); |
| 40 | + |
| 41 | +mongoose.Promise = Promise; |
| 42 | +mongoServer.getConnectionString().then((mongoUri) => { |
| 43 | + const mongooseOpts = { |
| 44 | + server: { |
| 45 | + auto_reconnect: true, |
| 46 | + reconnectTries: Number.MAX_VALUE, |
| 47 | + reconnectInterval: 1000, |
| 48 | + }, |
| 49 | + }; |
| 50 | + |
| 51 | + mongoose.connect(mongoUri, mongooseOpts); |
| 52 | + |
| 53 | + mongoose.connection.on('error', (e) => { |
| 54 | + if (e.message.code === 'ETIMEDOUT') { |
| 55 | + console.log(e); |
| 56 | + mongoose.connect(mongoUri, mongooseOpts); |
| 57 | + } |
| 58 | + console.log(e); |
| 59 | + }); |
| 60 | + |
| 61 | + mongoose.connection.once('open', () => { |
| 62 | + console.log(`MongoDB successfully connected to ${mongoUri}`); |
| 63 | + }); |
| 64 | +}); |
| 65 | +``` |
| 66 | +For additional information I recommend you to read this article [Testing a GraphQL Server using Jest with Mongoose](https://medium.com/entria/testing-a-graphql-server-using-jest-4e00d0e4980e) |
| 67 | + |
| 68 | + |
| 69 | +### Several mongoose connections simultaneously |
| 70 | +```js |
| 71 | +import mongoose from 'mongoose'; |
| 72 | +import MongodbMemoryServer from 'mongodb-memory-server'; |
| 73 | + |
| 74 | +mongoose.Promise = Promise; |
| 75 | + |
| 76 | +const mongoServer1 = new MongoMemoryServer(); |
| 77 | +const mongoServer2 = new MongoMemoryServer(); |
| 78 | + |
| 79 | +const mongooseOpts = { |
| 80 | + server: { |
| 81 | + promiseLibrary = Promise; |
| 82 | + auto_reconnect: true, |
| 83 | + reconnectTries: Number.MAX_VALUE, |
| 84 | + reconnectInterval: 1000, |
| 85 | + }, |
| 86 | +}; |
| 87 | + |
| 88 | +function addEvents(connection, mongoUri) { |
| 89 | + connection.on('error', (e) => { |
| 90 | + if (e.message.code === 'ETIMEDOUT') { |
| 91 | + console.log(e); |
| 92 | + connect(mongoUri, mongooseOpts); |
| 93 | + } |
| 94 | + console.log(e); |
| 95 | + }); |
| 96 | + |
| 97 | + connection.once('open', () => { |
| 98 | + console.log(`MongoDB successfully connected to ${mongoUri}`); |
| 99 | + }); |
| 100 | +} |
| 101 | + |
| 102 | +// Firstly create connection objects, which you may import in other files and create mongoose models. |
| 103 | +// Connection to databases will be estimated later (after model creation). |
| 104 | +const connections = { |
| 105 | + conn1: mongoose.createConnection(), |
| 106 | + conn2: mongoose.createConnection(), |
| 107 | + conn3: mongoose.createConnection(), |
| 108 | +}; |
| 109 | + |
| 110 | +mongoServer1.getConnectionString('server1_db1').then((mongoUri) => { |
| 111 | + connections.conn1.connect(mongoUri, mongooseOpts); |
| 112 | + addEvents(connections.conn1, mongoUri); |
| 113 | +}); |
| 114 | + |
| 115 | +mongoServer1.getConnectionString('server1_db2').then((mongoUri) => { |
| 116 | + connections.conn2.connect(mongoUri, mongooseOpts); |
| 117 | + addEvents(connections.conn2, mongoUri); |
| 118 | +}); |
| 119 | + |
| 120 | +mongoServer2.getConnectionString('server2_db').then((mongoUri) => { |
| 121 | + connections.conn3.connect(mongoUri, mongooseOpts); |
| 122 | + addEvents(connections.conn3, mongoUri); |
| 123 | +}); |
| 124 | + |
| 125 | +export default connections; |
| 126 | + |
| 127 | + |
| 128 | +// somewhere in other file |
| 129 | +import { Schema } from 'mongoose'; |
| 130 | +import { conn1, conn2, conn3 } from './file_above'; |
| 131 | + |
| 132 | +const userSchema = new Schema({ |
| 133 | + name: String, |
| 134 | +}); |
| 135 | + |
| 136 | +const taskSchema = new Schema({ |
| 137 | + userId: String, |
| 138 | + task: String, |
| 139 | +}); |
| 140 | + |
| 141 | +export default { |
| 142 | + User: conn1.model('user', userSchema), |
| 143 | + Task: conn2.model('task', taskSchema), |
| 144 | + UserOnServer2: conn3.model('user', userSchema), |
| 145 | +} |
| 146 | +``` |
| 147 | + |
| 148 | +### Simple Mocha test example |
| 149 | +```js |
| 150 | +import mongoose from 'mongoose'; |
| 151 | +import MongodbMemoryServer from 'mongodb-memory-server'; |
| 152 | + |
| 153 | +before(function(done) { |
| 154 | + const mongoServer = new MongodbMemoryServer(); |
| 155 | + mongoServer.getConnectionString().then((mongoUri) => { |
| 156 | + mongoose.connect(mongoUri, function(err) { |
| 157 | + done(err); |
| 158 | + }); |
| 159 | + }); |
| 160 | +}); |
| 161 | + |
| 162 | +describe('...', function() { |
| 163 | + it("...", function() { |
| 164 | + // ... |
| 165 | + }); |
| 166 | +}); |
| 167 | + |
| 168 | +``` |
| 169 | + |
| 170 | + |
| 171 | +## Credits |
| 172 | +Inspired by alternative runners for [mongodb-prebuilt](https://github.com/winfinit/mongodb-prebuilt): |
| 173 | +- [mockgoose](https://github.com/mockgoose/Mockgoose) |
| 174 | +- [mongomem](https://github.com/CImrie/mongomem) |
| 175 | + |
| 176 | +## License |
| 177 | + |
| 178 | +MIT |
0 commit comments