Code Monkey home page Code Monkey logo

mongomem's Introduction

MongoMem

This package provides an in-memory MongoDB Server. Designed with testing in mind, the server will allow you to connect your favourite ODM or client library to the MongoDB Server and run integration tests isolated from each other.

How it works This project is not an alternative in-memory MongoDB implementation. This runs using mongodb-prebuilt, which uses a MongoDB binary from NPM and runs it with the ephemeralForTest storage engine.

Note about AVA Test Runner The package was designed to run one server instance (max) at a time. As such it runs one server instance per test file in AVA (as a result of AVA using forked processes). This has no negative consequences but it does mean that you should call MongoDBServer.start() only once, at the top of an imported file or test file. Calling it in a helper method may result in either unexpected behaviour or multiple servers running per test file.

Usage

The example below uses async/await from ES7. If you wish to use the same syntax, you should transpile your code using babel-preset-es2017. Alternatively, if you are already using ES6 then you can convert it to the appropriate Promise syntax.

Available on NPM using: npm install mongomem --save-dev or yarn add mongomem --dev

See here for usage examples: https://coligo.io/javascript-async-await/

// helpers.js
import mongoose from 'mongoose'
import { MongoDBServer } from 'mongomem'

// MongoDBServer.debug = true;
let serverHasStarted = MongoDBServer.start();

export default {
  async getMongooseMock() {
      // 
      const mongooseInstance = new mongoose.Mongoose();
      await serverHasStarted;
    
      // MongoDBServer.getConnectionString() returns a new UUID4 on every call.
      // This allows you to get a unique database whilst utilising one in-memory server.
      let db = await MongoDBServer.getConnectionString();
      await mongooseInstance.connect(db, {promiseLibrary: Promise});
      
      // Re-assign original mongose models to new Mongoose connection
      Object.keys(mongoose.models).forEach(name => {
        const model = mongoose.models[name];
        mongooseInstance.model(name, model.schema);
      });
    
      return mongooseInstance;
  }
}

mongomem's People

Contributors

cimrie avatar thomas4019 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

mongomem's Issues

MongoDB Process not terminated

Hi!
I have following helper class for my tests using ava:

const mongoose = require('mongoose');
const MongoDBServer = require('mongomem').MongoDBServer;
const UserModel = require('../../models/users');

// MongoDBServer.debug = true;
const serverHasStarted = MongoDBServer.start();

class Util {
    async getMongooseMock() {
        const mongooseInstance = new mongoose.Mongoose();
        mongooseInstance.Promise = Promise;
        await serverHasStarted;
        const db = await MongoDBServer.getConnectionString();
        await mongooseInstance.connect(db);
        mongooseInstance.model('Users', UserModel.schema);
        return mongooseInstance;
    }

    beforeEach(test, func = () => {}) {
        test.beforeEach(async (t) => {
            const db = await this.getMongooseMock();
            const User = db.model('Users');
            await new Promise((resolve, reject) => {
                User.on('index', (error) => {
                    if (error) {
                        return reject(error);
                    }
                    return resolve();
                });
            });
            t.context.db = db;
            func(t);
        });
    }

    afterEach(test) {
        test.afterEach((t) => {
            t.context.db.disconnect();
        });
    }

    after(test) {
        test.after.always('cleanup', () => {
            MongoDBServer.tearDown();
        });
    }
}

module.exports = new Util();

When the teardown in after.always is called the check in your code helper.mongoBin.childProcess.connected is false, so the kill on the childprocess doesn't get called.

If I check on Ubuntu using  top -c -p $(pgrep -d',' -f mongo) the mongo process is still running. If I skip the if-check and call helper.mongoBin.childProcess.kill(); the server get's killed.

Am I doing something wrong?

mongodb-prebuilt dependency

It is right mongodb-prebuilt module is in devDependencies?

When I executed mongomem in ava testing, I got this error.

Error: Cannot find module 'mongodb-prebuilt'
    at Function.Module._resolveFilename (module.js:470:15)
    at Function.Module._load (module.js:418:25)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/somepath/node_modules/mongomem/build/MongoDBServer.js:19:24)
... and so on

get-port not working

When using this if I have mongodb running on port 27017 it still tries binding to that port instead of trying another open port.

For example when using ava with MongoDBServer.debug = true;.

➜  api.wvvw.me git:(master) ✗ yarn ava -- test/user.spec.js  --verbose
yarn ava v0.24.6
$ "/Users/xo/code/api.wvvw.me/node_modules/.bin/ava" test/user.spec.js --verbose

Mon, 26 Jun 2017 01:23:39 GMT mongodb-prebuilt-MongodHelper mongod stdout: 2017-06-26T10:53:39.106+0930 I CONTROL  [initandlisten] MongoDB starting : pid=72725 port=27017 dbpath=/var/folders/0s/cb83l2551dzdr09pym0ggckm0000gn/T/mongomem-72722HmQIjtY53Xsf 64-bit host=Bella.tardis
2017-06-26T10:53:39.107+0930 I CONTROL  [initandlisten] db version v3.5.5-13-g00ee4f5

Mon, 26 Jun 2017 01:23:39 GMT mongodb-prebuilt-MongodHelper mongod stdout: 2017-06-26T10:53:39.107+0930 I CONTROL  [initandlisten] git version: 00ee4f5156348477b9dd3f71b747104794f766c0
2017-06-26T10:53:39.107+0930 I CONTROL  [initandlisten] allocator: system
2017-06-26T10:53:39.107+0930 I CONTROL  [initandlisten] modules: none
2017-06-26T10:53:39.107+0930 I CONTROL  [initandlisten] build environment:
2017-06-26T10:53:39.107+0930 I CONTROL  [initandlisten]     distarch: x86_64
2017-06-26T10:53:39.107+0930 I CONTROL  [initandlisten]     target_arch: x86_64
2017-06-26T10:53:39.107+0930 I CONTROL  [initandlisten] options: { net: { port: 27017 }, security: { authorization: "disabled" }, storage: { dbPath: "/var/folders/0s/cb83l2551dzdr09pym0ggckm0000gn/T/mongomem-72722HmQIjtY53Xsf", engine: "ephemeralForTest" } }
2017-06-26T10:53:39.108+0930 E NETWORK  [initandlisten] listen(): bind() failed Address already in use for socket: 0.0.0.0:27017
2017-06-26T10:53:39.108+0930 E NETWORK  [initandlisten]   addr already in use
2017-06-26T10:53:39.108+0930 E NETWORK  [initandlisten] Failed to set up sockets during startup.
2017-06-26T10:53:39.108+0930 E STORAGE  [initandlisten] Failed to set up listener: InternalError: Failed to set up sockets
2017-06-26T10:53:39.108+0930 I NETWORK  [initandlisten] shutdown: going to close listening sockets...
2017-06-26T10:53:39.108+0930 I NETWORK  [initandlisten] shutdown: going to flush diaglog...

Mon, 26 Jun 2017 01:23:39 GMT mongodb-prebuilt-MongodHelper mongod stdout: 2017-06-26T10:53:39.113+0930 I CONTROL  [initandlisten] now exiting

Mon, 26 Jun 2017 01:23:39 GMT mongodb-prebuilt-MongodHelper mongod stdout: 2017-06-26T10:53:39.113+0930 I CONTROL  [initandlisten] shutting down with code:48

  ✖ start server Rejected promise returned by test
Mon, 26 Jun 2017 01:23:39 GMT mongodb-prebuilt-MongodHelper mongod close: 48

  1 test failed [10:53:39]

  start server

  Rejected promise returned by test

  Rejection reason:

    "Mongod shutting down"


error Command failed with exit code 1.

Can not remove Temp dir

Hi. I'm trying to run the test, use 'ava' command, but when call method 'server.tmpFile.removeCallback();', it throw a error as below:
[Error: EBUSY: resource busy or locked, unlink 'C:\Users\LIJO9\AppData\Local\Temp\mongomem-268688a5fvz9AA6ck\mongod
.lock']

1523706612 1

I don't know why the .lock file can not be deleted, do you have any suggestion? Thanks a lot.

Error: Cannot find module 'babel-runtime/regenerator'

I'm trying this module out to use with Ava, I've taken the example code (switched esm to requireJS) but im unable to get it running.

const test = require('ava');
const MongoDBServer = require('mongomem');

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

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

  // 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.
});

returns

  Uncaught exception in src/parse-env-var.test.js

  /Users/me/sites/projectName/node_modules/mongomem/build/MongoDBServer.js:7

  Error: Cannot find module 'babel-runtime/regenerator'

I've tried on several versions of node (8.9.0 10.14.0 and 11.3.0) but unable to get anything working. Fresh node_module installs with rm -rf package-lock.json to be safe as well

Server never starts, with no error

Hi. I'm trying to use this lib (for ava tests) but I can't get the server working.

The following example hangs and the server never seems to start :

(async function() {
    console.log('start');
    MongoDBServer.debug = true;
    await MongoDBServer.start();
    console.log('started');
})();

This outputs:

start
Fri, 28 Jul 2017 11:15:47 GMT mongodb-prebuilt-MongodHelper mongod stdout: 2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten] MongoDB starting : pid=23655 port=35493 dbpath=/tmp/mongomem-23637qKAvX7uT2BP6 64-bit host=ouistiti
2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten] db version v3.5.10-191-g6cc2dfe7ed
2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten] git version: 6cc2dfe7edd312b8596355edef454e15988e350e
2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten] allocator: tcmalloc
2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten] modules: none
2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten] build environment:
2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten]     distarch: x86_64
2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten]     target_arch: x86_64
2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten] options: { net: { port: 35493 }, security: { authorization: "disabled" }, storage: { dbPath: "/tmp/mongomem-23637qKAvX7uT2BP6", engine: "ephemeralForTest" } }

Fri, 28 Jul 2017 11:15:47 GMT mongodb-prebuilt-MongodHelper mongod stdout: 2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten] 
2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten] ** NOTE: This is a development version (3.5.10-191-g6cc2dfe7ed) of MongoDB.
2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten] **       Not recommended for production.
2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten] 
2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten] ** WARNING: This server is bound to localhost.
2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten] **          Remote systems will be unable to connect to this server. 
2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten] **          Start the server with --bind_ip <address> to specify which IP 
2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten] **          addressses it should serve responses from, or with --bind_ip_all to
2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten] **          bind to all interfaces. If this behavior is desired, start the
2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten] **          server with --bind_ip 127.0.0.1 to disable this warning.
2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten] 
2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten] 
2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten] 
2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten] ** NOTE: The ephemeralForTest storage engine is for testing only. 
2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten] **       Do not use in production.
2017-07-28T13:15:47.272+0200 I CONTROL  [initandlisten] 
2017-07-28T13:15:47.273+0200 I FTDC     [initandlisten] Initializing full-time diagnostic data capture with directory '/tmp/mongomem-23637qKAvX7uT2BP6/diagnostic.data'
2017-07-28T13:15:47.273+0200 I COMMAND  [initandlisten] setting featureCompatibilityVersion to 3.6          

Yet, /tmp/mongomem-23637qKAvX7uT2BP6/diagnostic.data seems to be correcly created:

$ tree /tmp/mongomem-23637qKAvX7uT2BP6/diagnostic.data/
/tmp/mongomem-23637qKAvX7uT2BP6/diagnostic.data/
└── metrics.2017-07-28T11-15-47Z-00000

I'm using node 8.1.3, npm 5.3.0 and the latests release of mogomem.

Any help ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.