Code Monkey home page Code Monkey logo

mongo-mock's Introduction

mongo-mock     Build Status

This is an in-memory 'pretend' mongodb. The goal is to make the interface compatible with the real mongodb module so they are interchangeable.

There are a TON of features for mongo and I can't write them all myself- so pull requests are encouraged! My initial goal was to provide basic CRUD operations to enable this to work as a throw-something-together tool.

Why?

Maybe you don't want to (or can't) connect to a MongoDB instance for your tests?
Maybe you want to throw together a quick example app?

Demo code

var mongodb = require('mongo-mock');
mongodb.max_delay = 0;//you can choose to NOT pretend to be async (default is 400ms)
var MongoClient = mongodb.MongoClient;
MongoClient.persist="mongo.js";//persist the data to disk

// Connection URL
var url = 'mongodb://localhost:27017/myproject';
// Use connect method to connect to the Server
MongoClient.connect(url, {}, function(err, client) {
  var db = client.db();
  // Get the documents collection
  var collection = db.collection('documents');
  // Insert some documents
  var docs = [ {a : 1}, {a : 2}, {a : 3}];
  collection.insertMany(docs, function(err, result) {
    console.log('inserted',result);

    collection.updateOne({ a : 2 }, { $set: { b : 1 } }, function(err, result) {
      console.log('updated',result);

      collection.findOne({a:2}, {b:1}, function(err, doc) {
        console.log('foundOne', doc);

        collection.removeOne({ a : 3 }, function(err, result) {
          console.log('removed',result);

          collection.find({}, {_id:-1}).toArray(function(err, docs) {
            console.log('found',docs);
            
            function cleanup(){            
              var state = collection.toJSON();
              // Do whatever you want. It's just an Array of Objects.
              state.documents.push({a : 2});
              
              // truncate
              state.documents.length = 0;
              
              // closing connection
              db.close();
            }
            
            setTimeout(cleanup, 1000);
          });
        });
      });
    });
  });
});

Install

Well, you know.. the usual:

$ npm install mongo-mock

mongo-mock's People

Contributors

angelo-hub avatar chrishalbert avatar conlanpatrek avatar dependabot[bot] avatar detrohutt avatar dir01 avatar execfera avatar floby avatar gbarbieru avatar htbkoo avatar konsumer avatar kub1x avatar linusu avatar mjclyde avatar onsjo avatar pstromberg98 avatar root-core avatar samjoch avatar seancannon avatar seanspradlin avatar shaunburdick avatar tanukisharp avatar tobiasnickel avatar williamkapke avatar ykantema avatar zenit1scada 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  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  avatar  avatar  avatar  avatar  avatar  avatar

mongo-mock's Issues

deleteMany does not properly manage promises

If the callback parameter is not set when calling deleteMany, the function does not return a promise.

The issue is the check for callback is done inside the callback for cursor() instead of doing so at deleteMany function level.

Subdocument updates?

Hi, thanks for creating this.

I'm having some trouble updating fields in nested documents - for example:

col.update({
  name: 'foo',
}, {
  $set: {
    'pets.0.type': 'dog'
  }
})

Here's an SO thread describing the type of query I'm talking about.

Is this functionality not implemented?

db: [Function: NotImplemented]

Is anybody working in this implementation?

I use it i my project because it constantly switch from a database to another, and is impossible to test.

Thanks in avance.

ObjectID(undefined) after update

When you update a document, all the fields with type equal to ObjectID get messed up (except for the "_id" field).

Sample code

const mongodb = require('mongo-mock');
const ObjectID = require('mongo-mock').ObjectID;

async function main() {
  const db = await mongodb.MongoClient.connect('mongodb://fake.db:1111/db');
  const collection = db.collection('collection');

  const _id = new ObjectID();
  const otherId = new ObjectID();
  const obj = { _id, otherId, name: 'insert'};
  
  await collection.insertOne(obj);
  const res1 = await collection.findOne({ _id });
  
  await collection.updateOne({ _id }, { $set: { name: 'update' } });
  const res2 = await collection.findOne({ _id });

  console.log(res1.otherId);
  console.log(res2.otherId);
}

main().then(() => { process.exit() });

Expected result
res1.otherId should be equal to res2.otherId.

Actual result
res2.otherId is equal to ObjectID(undefined).

bug: findOneAndUpdate throws ModifyJsError error if no records found for given filter

I tried to mock one of my findOneAndUpdate queries that are working on my mongodb instance, and I've encountered this ModifyJsError error...
Expected result:
If no records were found by filter object, the result of findOneAndUpdate function returns null;
Actual result:
findOneAndUpdate throws ModifyJsError error if no records were found by the filter object.

Sample code:

var mongodb = require('mongo-mock');
mongodb.max_delay = 0;//you can choose to NOT pretend to be async (default is 400ms)
var MongoClient = mongodb.MongoClient;
MongoClient.persist = 'mongo.js'
var ObjectID = require('bson-objectid');
var url = 'mongodb://localhost:27017/myproject';

MongoClient.connect(url, {}, async function(err, db) {
  var collection = db.collection('documents');
  collection.insert({ lastStatus: 'not-pending'}); // <------ Non 'pending' status
  const queryFilter = { lastStatus: 'pending' };
  const queryUpdate = {
    $set: {
      lastStatus: 'processing',
      lastUpdated: Date.now()
    }
  };
  const res = await collection.findOneAndUpdate(queryFilter, queryUpdate);
  console.log(res);
});

Cli output:

└─▪ DEBUG=* node ./findOneAndUpdate-index.js 
  mongo-mock:mongo_client connecting localhost:27017/myproject +0ms
  mongo-mock:collection initializing instance of `system.namespaces` with 1 documents +2ms
  mongo-mock:collection initializing instance of `system.indexes` with 0 documents +1ms
  mongo-mock:db myproject open +1ms
  mongo-mock:collection initializing instance of `documents` with undefined documents +0ms
  mongo-mock:collection insert {"lastStatus":"not-pending"} +1ms
  mongo-mock:collection documents.update:  {"lastStatus":"pending"} +0ms
  mongo-mock:db documents persist() - creating _id index +2ms
  mongo-mock:mongo_client persisting to mongo.js +1ms
  mongo-mock:collection documents.update:  [] +1ms
  mongo-mock:collection documents.update:  checking for index conflicts +0ms
/home/pavel/git-repos/temp/mongo-mock-bug/node_modules/modifyjs/dist/bundle.js:252
      throw e;
      ^

ModifyJsError: cannot use the part 'lastStatus' to traverse undefined
    at ModifyJsError (/home/pavel/git-repos/temp/mongo-mock-bug/node_modules/modifyjs/dist/bundle.js:141:11)
    at findModTarget (/home/pavel/git-repos/temp/mongo-mock-bug/node_modules/modifyjs/dist/bundle.js:250:15)
    at /home/pavel/git-repos/temp/mongo-mock-bug/node_modules/modifyjs/dist/bundle.js:197:22
    at /home/pavel/git-repos/temp/mongo-mock-bug/node_modules/modifyjs/dist/bundle.js:68:5
    at Array.forEach (<anonymous>)
    at Object.each (/home/pavel/git-repos/temp/mongo-mock-bug/node_modules/modifyjs/dist/bundle.js:67:32)
    at /home/pavel/git-repos/temp/mongo-mock-bug/node_modules/modifyjs/dist/bundle.js:187:9
    at /home/pavel/git-repos/temp/mongo-mock-bug/node_modules/modifyjs/dist/bundle.js:68:5
    at Array.forEach (<anonymous>)
    at Object.each (/home/pavel/git-repos/temp/mongo-mock-bug/node_modules/modifyjs/dist/bundle.js:67:32)

node version: 10.15.1
npm version: 6.4.1

Merge Policy

Before we merge any of these new PRs with our new maintainers and get this project going, I'd like to implement a branching release strategy like gitflow into this project, I'd like to have feature branches for release tags to keep our semversion-ing in place with more maintainers coming on board, and feature build outs.

For example: I think bulkOps #67 and #63 should be held off and included in version release 3.4.0 while some of the patch PRs should be in 3.3.1, and therefor for major and minor semversion's I'd like to point PR's to a release branch, so we can make sure the additional features are well tested together before publshing.

@pidid what do you think?

We have no linting strategy

We should use eslint and have a linting policy, I prefer airbnb base but I understand if that's too strict, we should try to support node 6 and above

Circle CI failing + needs update

The build is failing on the use of const. It must be testing with an old version of Node.

Additionally, it seems the version of CircleCI it uses is being sunset in ~30 days! It looks like the code might need some minor tweaks to upgrade it.

lib/collection.js fields sniff fails on limit 1

This logic will fail when { limit: 1, fields: undefined } because well, that's what it'll do.
Suggest checking for !(fields in args).

lib/collection.js

    case "object,object,function":
      //sniff for a 1 or -1 to detect fields object
      if (!args[1] || Math.abs(args[1][0]) === 1) {
        options.fields = args[1];
      }
      else {
        if(args[1].skip) options.skip = args[1].skip;
        if(args[1].limit) options.limit = args[1].limit;
        if(args[1].fields) options.fields = args[1].fields;
        if(args[1].projection) options.fields = args[1].projection;
      }

doesn't work from jest

Any idea why the mocks aren't working in jest (latest version 23.x)? Code works fine outside of jest

describe('loadClinicalData',` () => {
  it('test something', async () => {
    const mongodb = require('mongo-mock')
    mongodb.max_delay = 0 // you can choose to NOT pretend to be async (default is 400ms)
    const { MongoClient } = mongodb
    MongoClient.persist = 'mongo.js'// persist the data to disk

    // Connection URL
    const url = 'mongodb://localhost:27017/myproject'
    console.log('connecting to url', url)
    // Use connect method to connect to the Server
    MongoClient.connect(url, {}, (err, db) => {
      console.log('connected')
    })
  })
})

Never logs "connected" to console.

collection.countDocuments is undefined

recent versions of the mongodb driver have deprecated the collection.count() method in favor of collection.countDocuments() and collection.estimatedDocumentCount().

trying mock modern apps that use the collection.countDocuments() method end up throwing 'countDocuments is undefined' errors.

Typescript Typedefs

Would be worth adding typescript definitions to DefinitelyTyped.

Should be easy enough to take the MongoDB typings and simply cut out the parts that aren't implemented for mongo-mock.

v3.3.0 isn't published on NPM

Would be nice if you could publish the latest version to NPM. I'm currently unable to use mongo-mock, due to receiving a lodash version conflict / error:

  Uncaught exception in src\tests.js
  c:\dev\my-project\node_modules\mongo-mock\lib\db.js:221
  TypeError: _.where is not a function

This ain't a problem in the latest version.

MongoClient.connect() doesn't exist like mongodb's one

Hi,

I have noticed the following issue. When the connection is not closed, the script never exits. I am not arguing that I should not have a finally, just that I did not expect this difference.

Thanks,

$ cat mongodb-connect.js
const mongodb = require('mongodb');
mongodb.MongoClient.connect('mongodb://dummy-host/')
    .then((db) => console.log("Connected mongo-mock"));

$ node mongodb-connect.js
(node:38853) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): MongoError: failed to connect to server [dummy-host:27017] on first connect

$ cat mongo-mock-connect.js
const mongodb = require('mongo-mock');
mongodb.MongoClient.connect('mongodb://dummy-host/')
    .then((db) => console.log("Connected mongodb"));

$ node mongo-mock-connect.js
Connected mongodb
^C

Mongoose mocking

Love this project, ran into a hiccup. I thought that since mongoose uses mongodb for its driver, I could mock mongoose with it, but there are some incompatibilities because the default (latest) mongo driver exposes much more than this one does. Example. Mongoose is expecting the Collection class to be available.

I understand if your use case is not to match 100% of the API, that's a tough thing to keep up with, but I applaud the effort. If you don't plan to support it, would you happen to know of alternatives that would mock mongodb or mongoose in-memory?

Documents cleanup between test cases

Hi, thanks a lot for creating this package! It is really useful for unit tests or for doing some quick hacks.

However I would like to ask if there is an API to clean up the in-memory database/documents between few test cases in one test suite (apologies but seems this is not mentioned in the readme or in other issues)?

Or should I call the remove() to clean up?

Thank you. :)

Missing DBRef constructor

I use mongo-mock and its awesome, the only thing that I had to add is the db reference constructor that in mongo db is at the same level of the ObjectId constructor, I just wrote this code:

import mongoMockDb from 'mongo-mock';

mongoMockDb.DBRef = function(name, id) {
  this.$ref = name;
  this.$id = new mongoMockDb.ObjectId(id);
  this.oid = id;
};

Maybe you can just add it.
Thank you, great job!!

find/findOne by id doesn't return records

mongo-mock find function behaves differently from mongodb when calling find by id.
It's hard to mock the mongodb using mongo-mock if it behaves differently :)

Example:

var mongodb = require('mongo-mock');
mongodb.max_delay = 0;//you can choose to NOT pretend to be async (default is 400ms)
var MongoClient = mongodb.MongoClient;
MongoClient.persist = 'mongo.js'
var ObjectID = require('bson-objectid');
var url = 'mongodb://localhost:27017/myproject';

MongoClient.connect(url, {}, function(err, db) {
  var collection = db.collection('documents');
  var doc = { a: 1 };
  collection.insert(doc, function(err, result) {
    const id = result.insertedIds[0].toString();
    console.log('inserted id:', id);
    
    // Doesn't work:
    collection.findOne({_id: id }, function(err, result){
      console.log('found:', result);
    });
     // Doesn't work:
    collection.find(ObjectID(id)).toArray(function(err, result){
      console.log('found using ObjectId:', result);
    });
    
    // Works, but outputs DepricationWarning:
    // (node:11633) [DEP0079] DeprecationWarning: Custom inspection function on Objects via .inspect() is deprecated
    collection.find({_id: ObjectID(id) }).toArray(function(err, result){
      console.log('found using {_id:ObjectId(id)}:', result);
    });
    // Works
    collection.findOne({_id: ObjectID(id) },function(err, result){
      console.log('foundOne using {_id:ObjectId(id)}:', result);
    });
  });

Official find doc:
https://docs.mongodb.com/manual/reference/method/db.collection.find/

Code sample: mongo-mock-getById.zip

node version: 10.15.1
npm version: 6.4.1

Unable to insert with _id=0

Trying to insert a row with _id=0 or _id="" will result in a row with an autogenerated _id.

This is different from mongo behavior which accepts those.

modify should catch the ModifyJsError and return an empty row

Currently if there is a filter on findOneAndUpdate and returning a document there is no matching row the modify function does not catch an error for asyncish.

ModifyJsError: cannot use the part 'colName' to traverse undefined

This should have instead returned an empty row for the update.

findOneAndUpdate with returnNewDocument should be atomic

Using findOneAndUpdate with returnNewDocument may return the current version of a document as updated by another call - it should return the document as modified by the current request.

We noticed this using $inc of 1 for a sequence. Sometimes it would return the same value, as the returnNewDocument is likely waiting till the next event loop.

So this presently breaks the ability to mock auto increment by a collection of promises getting a collection of unique ids

Bug: update after upsert does not work

If some document had been inserted into collection by upsert method (update with upsert flag option), when it can't be updated later.

Example code:

collection.update({ key: 'KEY' }, { key: 'KEY', value: 'VALUE-1' }, { upsert: true }, (err1) => {
  collection.update({ key: 'KEY' }, { key: 'KEY', value: 'VALUE-2' }, (err2) => {
    const document = collection.findOne({ key: 'KEY' }, (err3, doc) => {
      if(err1 || err2 || err3) {
        console.log('Error occured: ', err1, err2, err3);
      } else {
        console.log('Document: ', document);
      }
    })
  })
})

After execution, { key: 'KEY', value: 'VALUE-1' } will be printed. But valid result is { key: 'KEY', value: 'VALUE-2' }

TypeError: Cannot read property 'replace' of null (MongoClient.connect)

This is our code that we were using to connect to the mongo-mock, which works find in mongodb:

MongoClient.connect(process.env.MONGODB_CONFIG)
         |             ^
      63 |   .then(client => {
      64 |     mongo = client.db('myDb');

The problem was that mongo was depending on us passing in a dbname as the path parameter of the URL:

MongoClient.connect = function(url, options, callback) {
...
  url = urlparse(url);
...
  var dbname = url.pathname.replace(/^\//, '');
  return new Db(dbname, server).open(callback);

...We were not passing in dbname.

The workaround was this:

MongoClient.connect(process.env.MONGODB_CONFIG + '/myDb')
.then(client => {
  mongo = client;

...That is, I needed to send the db in as a string.

Cannot make MongoClient.load to work

Is there any example how to use MongoClient.load to load mock data from file?

I was trying this way but could not get it to work, the .findOne method was still returning null after the data was loaded from file.
The contents of users.js was created when I use MongoClient.persist = "users.js"
so it has all the correct data.

If I'm not use the .load method correctly then please let me know how to use it.


const mongodb = require('mongo-mock');
mongodb.max_delay = 10;//you can choose to NOT pretend to be async (default is 400ms)
let MongoClient = mongodb.MongoClient;
MongoClient.load(__dirname + '/users.js');

const url = 'mongodb://localhost:27017/myproject';
let mydb;
let mycoll;

MongoClient.connect(url).then(db => {
  mydb = db;
  return db.collection('users')
}).then(coll => {
  mycoll = coll;
}).then(_ => {
  console.log(`AFTER INSERT: ${_}`);
  return mycoll.findOne({assocId: "225101"});
}).then(res => {
  console.log(`FOUND: ${JSON.stringify(res)}`);
  mydb.close()
});

Persist and load

Lost some time before understanding that persist="file" needs load("file"); I suggest a unified function that covers both with appropriate toggles. store("json.file"), store({read: "json.file", write: "json2.file"}) or something of that nature.

As a folk who hasn't much mongo, this library has been so helpful to me. Thanks to all contributors!

A lack of mantanience on this project

I've had some pending PR's for the last two months with no input, it's completely understandable if you're too busy @williamkapke as acting representation on the Node.js Board of Directors.

I'm opening this as a discussion as to whether to move the project forward and continue to add features, I should branch it, or instead have more people added to this project as moderators, that have the time to discuss and review Pull Requests.

Thanks for hearing me out!
Angelo

Uncatchable throws

Using version 3.8.1 of mongo-mock, and in some circumstances, when a function throws, it is uncatchable. Hereafter is a repro, in which I actually added 2 tests because I think they are kind of related.

package.json

{
  "name": "mongo-mock-async-issue-repro",
  "main": "index.js",
  "dependencies": {
    "mongo-mock": "^3.8.1"
  }
}

index.js

const mongodb = require('mongo-mock');

const testHangingCallback = (client) => {
    client.db('myDb').collection('myCollection').insertOne(
        { _id: 1 },
        (error) => {
            if (error) {
                console.log('error:', error);
                return;
            }
            console.log('OK, then what ?');
        }
    );
};

const testHangingAsync = async (client) => {
    await client.db('myDb').collection('myCollection').insertOne({ _id: 1 });
    console.log('OK, then what ?');
};

const testUncatchableThrow = async (client) => {
    try {
        console.log('Try to catch');

        await client.db('myDb').collection('myCollection').findOneAndUpdate({ _id: 1});

        console.log('FAILURE');
    } catch (error) {
        console.log('Nice catch!');
    }
};

const main = async () => {
    mongodb.max_delay = 1;

    const client = await mongodb.MongoClient.connect(
        'mongodb://somewhere/someDb',
        { useNewUrlParser: true }
    );

    // testHangingCallback(client);
    // await testHangingAsync(client);
    // await testUncatchableThrow(client);
};

main();

Then, uncomment either testHangingCallback, testHangingAsync or testUncatchableThrow and run it.

testHanging*

Expected result:

OK, then what ?
<end-of-program>

Actual result

OK, then what ?

The program hangs forever, like a timer is started and never stopped, locking the event loop.

testUncatchableThrow

Expected result

Try to catch
Nice catch!

Worst case scenario, a big bug let this work, I'm expecting:

Try to catch
FAILURE

Actual result

Try to catch
<my-path>/mongo-mock-async-issue-repro/node_modules/modifyjs/dist/bundle.js:168
  if (!isPlainObject(mod)) throw ModifyJsError("Modifier must be an object");
                           ^

ModifyJsError: Modifier must be an object
    at ModifyJsError (<my-path>/mongo-mock-async-issue-repro/node_modules/modifyjs/dist/bundle.js:141:11)
    at _modify (<my-path>/mongo-mock-async-issue-repro/node_modules/modifyjs/dist/bundle.js:168:34)
    at modify (<my-path>/mongo-mock-async-issue-repro/node_modules/modifyjs/dist/bundle.js:163:10)
    at modify (<my-path>/mongo-mock-async-issue-repro/node_modules/mongo-mock/lib/collection.js:495:17)
    at Timeout._onTimeout (<my-path>/mongo-mock-async-issue-repro/node_modules/mongo-mock/lib/collection.js:467:26)
    at ontimeout (timers.js:436:11)
    at tryOnTimeout (timers.js:300:5)
    at listOnTimeout (timers.js:263:5)
    at Timer.processTimers (timers.js:223:10)

$push ObjectID into array returns ObjectID(undefined)

First off, thank you for this amazing work, might consider contributing. The issue I'd like to report is that, for some reason, when using $push to insert an ObjectID into an array, the resulting ObjectID that is inserted is undefined.

Reproduction code, using the last 3.0.0 release:

async function main() {
  const mongodb = require('mongo-mock');
  const ObjectID = require('mongo-mock').ObjectID;
  const db = await mongodb.MongoClient.connect('mongodb://fake.db:1111/db');
  const collection = db.collection('collection');
  const testID = new ObjectID();

  await collection.insertOne({ test: '123' });
  await collection.updateOne({ test: '123' }, { $push: { testArray: testID }});
  const res = await collection.findOne({ test: '123' });
  console.log(testID); // ObjectID(some-hex-string)
  console.log(res.testArray[0]); // ObjectID(undefined)
}

main().then(() => { process.exit() });

Thanks for your time!

Wrong sort of null values

#11 was implemented but there is a difference when null values are sorted and it causes issues when testing it.

mongo

> col.insertMany([{n: 1, index:3}, {n: 2}, {n:3, index:0}, {n:4}])
{
	"acknowledged" : true,
	"insertedIds" : [
		ObjectId("5ca7d8833ffd7df2a76ff606"),
		ObjectId("5ca7d8833ffd7df2a76ff607"),
		ObjectId("5ca7d8833ffd7df2a76ff608"),
		ObjectId("5ca7d8833ffd7df2a76ff609")
	]
}
> col.find().sort({index: 1})
{ "_id" : ObjectId("5ca7d8833ffd7df2a76ff607"), "n" : 2 }
{ "_id" : ObjectId("5ca7d8833ffd7df2a76ff609"), "n" : 4 }
{ "_id" : ObjectId("5ca7d8833ffd7df2a76ff608"), "n" : 3, "index" : 0 }
{ "_id" : ObjectId("5ca7d8833ffd7df2a76ff606"), "n" : 1, "index" : 3 }

mongo-mock

col.insertMany([{n: 1, index:3}, {n: 2}, {n:3, index:0}, {n:4}])
col.find().sort({index: 1}).toArray()
[ { n: 2, _id: ObjectID(5ca7d896392bb0dbef37e207) },
  { n: 3, index: 0, _id: ObjectID(5ca7d896392bb0dbef37e208) },
  { n: 4, _id: ObjectID(5ca7d896392bb0dbef37e209) },
  { n: 1, index: 3, _id: ObjectID(5ca7d896392bb0dbef37e206) } ]

mocha does not exit after closing connection to mock mongodb

On line # 162 of db.js there is a call to setTimeout that is supposed to keep hosting process running until at least one connection is open .

open = setInterval(function () {}, 600000)

In order to let process exit when connections are closed there is a corresponding line # 26 at db.js

clearInterval(open);

But setTimeout is called twice when I run MongoClient.connect. So one of two timers stays scheduled and mocka keeps running after closing connection to mock mongodb.

project is not implemented

let res = await this.connection.find().project({ _id: 0}).toArray();
does not work, the deprecated method
let res = await this.connection.find({},{ _id: -1}).toArray();
does

Project state? Serialization of db?

I am looking for a way to have a mongodb api without having to maintain a mongodb server, like for developing or for small apps.

It would be acceptable to write the entire db to a file every so often and to read the file into memory at startup.

Is that possible?

Is this project complete enough that it could be a pretend mongodb for mongoose?

findOneAndUpdate with $and

I'm using mongo-mock version 3.8.1 and I run this query:

// sample values:
const who = 123;
const timestamp = 1;
const what = {
    one: 'one',
    two: two
};

await collection.findOneAndUpdate(
      { $and: [{ _id: who }, { ts: { $lt: timestamp } }] },
      { $set: what },
      { upsert: true }
);

This works perfectly with a real MongoDB 3.6, but fails with mongo-mock. I run this with Jest (unit test) and get the following:

ModifyJsError: Invalid modifier specified $and

      at ModifyJsError (../node_modules/modifyjs/dist/bundle.js:141:11)
      at ../node_modules/modifyjs/dist/bundle.js:186:27
      at ../node_modules/modifyjs/dist/bundle.js:68:5
          at Array.forEach (<anonymous>)
      at Object.each (../node_modules/modifyjs/dist/bundle.js:67:32)
      at _modify (../node_modules/modifyjs/dist/bundle.js:183:7)
      at modify (../node_modules/modifyjs/dist/bundle.js:163:10)
      at upsertClone (../node_modules/mongo-mock/lib/collection.js:526:57)
      at Timeout._onTimeout (../node_modules/mongo-mock/lib/collection.js:447:27)

The thing is, I cannot catch it. When I log before and after await, I see the log before but not the one after, so I assume the promise returned never resolves nor rejects.

If it can help you to investigate, we have found that on the following line, the second call to modifyjs (from left to right) should probably not be based on the selector. The selector contains $and, and modifyjs seems to not support this operator.
https://github.com/williamkapke/mongo-mock/blob/master/lib/collection.js#L526

However, I've tried to quickly tweak the code of mongo-mock but couldn't fix the problem, so the above assumption may be wrong. Note sure.

Thank you for your consideration.

ObjectID differ between mongodb and mongo-mock

I'm testing some code that uses mongodb to find/update/delete objects looking them up by their _id. However as the tested code uses require('mongodb').ObjectID and mongo-mock uses a different version of it, the tested code can't find the objects. This is really annoying ...

Mixed projections types not allowed

Hey guys!

Loving the project, it allows me to really test my express app from a mocha testsuite but today I ran into an issue when I was refactoring, this query:

db.getCollection('position').findOne({
            status: 0
        }, {
            sort: [ [ 'priority', 'desc' ] ]
        })

works against a normal mongo database, but in mongo-mock it fails with:

mongo-mock:collection findOne {"query":{"status":0},"fields":{"sort":[["priority","desc"]]},"skip":0,"limit":0} callback=undefined +0ms
mongo-mock:cursor initializing cursor +0ms
Error: Mixed projections types not allowed

Is it something Im doing wrong?

MongoClient.connect failed to return db for non-callback.

for mongdodb, MongoClient allow to call the connection "MongoClient.connect(url)" without callback function provided. This mock have issue for this scenario.

Found is missing 'return' for below code:
lib/mongo_client.js line 22
return new Db(dbname, server).open(callback);

Provide a simple API to insert test data into the fake DB

When using mongo-mock inside unit tests for example, it's a bit tedious to use the mongodb api to insert data (MongoClient.connect, with callback hell and everything else).

It would be great to have a simple, synchronous API to insert test data and clear everything.

Here's an example of what I have in mind:

import mongoMock from 'mongo-mock';

beforeEach(() => {
    mongoMock.clearTestData();
    mongoMock.insertTestData('collection', [...data]);
    // Or maybe...
    mongoMock.insertTestData('dbUri', 'collection', [...data]);
});

I don't know if it's possible in your library, but that would make writing test way easier.

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.