Use mock MongoDB server for unit test
Asked Answered
F

4

17

I have to implement nosetests for Python code using a MongoDB store. Is there any python library which permits me initializing a mock in-memory MongoDB server?

I am using continuous integration. So, I want my tests to be independent of any MongoDB running server. Is there a way to mock mongoDM Server in memory to test the code independently of connecting to a Mongo server?

Thanks in advance!

Fragmentary answered 10/4, 2013 at 0:42 Comment(0)
P
14

You could try: https://github.com/vmalloc/mongomock, which aims to be a small library for mocking pymongo collection objects for testing purposes.

However, I'm not sure that the cost of just running mongodb would be prohibitive compared to ensuring some mocking library is feature complete.

Postoperative answered 15/4, 2013 at 14:0 Comment(3)
it would be really nice to get an example of how mongoengine and mongomock can play nicely together.Echolocation
Make sure you have good compatibility with versions later than 3.0. I failed mocking my collections with all the frameworks I tried with immediately after I upgraded the server and driver (pymongo)Ailee
@Echolocation Simply two lines of code: import mongomock client = mongomock.MongoClient() then you're good to go. After that you could use client.my_db.my_coll.insert_one({'a': 1}) exactly the way you're using pymongo.Crenshaw
T
4

I don’t know about Python, but I had a similar concern with C#. I decided to just run a real instance of Mongo on my workstation pointed at an empty directory. It’s not great because the code isn’t isolated but it’s fast and easy.

Only the data access layer actually calls Mongo during the test. The rest can rely on the mocks of the data access layer. I didn’t feel like faking Mongo was worth the effort when really I want to verify the interaction with Mongo is correct anyway.

Tatty answered 10/4, 2013 at 2:10 Comment(3)
+1 I don't understand the desire to test everything in isolation. The best you can hope for is that it behaves like the real thing. Just test the real thing. Configure a dedicated test database.Direction
That's a valid point, but one reason for testing in isolation is that you can more easily give it to other people so they can test in their environment too. That becomes more onerous (though it's probably worth it in this case) if they have to set up an external process too.Wuhan
And to add to that if the tests are meant to run in pipeline you cannot be sure that you would have the DB installed .Rework
G
2

You can use Ming which has an in-memory mongo db pymongo connection replacement.

import ming
mg = ming.create_datastore('mim://')
mg.conn # is the connection
mg.db # is a db with no name
mg.conn.somedb.somecol
# >> mim.Collection(mim.Database(somedb), somecol)
col = mg.conn.somedb.somecol
col.insert({'a': 1})
# >> ObjectId('5216ac3fe0323a1218f4e9aa')
col.find().count()
# >> 1
Geniculate answered 23/8, 2013 at 0:28 Comment(3)
The same as above. I tried ming with MongoDB => 3.0 and failed most of the times because ming is not meant for this. It is more and more unreliable as long as the complexity increases.Ailee
@HéctorValverdePareja what are you trying to do that fails? As you can see from the snippet, insert and find work fine.Geniculate
Sorry, when I said 'above' I meant the comment I added in the approved answer. It's about compatibility. Ming didn't support newest version of pymongo (later to 3.0), for example the function "insert_one()" instead "insert()" is not supported by Ming (or wasn't 2 - 3 months ago when I was playing with it.Ailee
E
1

I am also using pymongo and MockupDB is working very well for my purpose (integration tests).

To use it is as simple as:

from mockupdb import *
server = MockupDB()
port = server.run()
from pymongo import MongoClient
client = MongoClient(server.uri)
import module_i_want_to_patch
module_i_want_to_patch.client = client

You can check the official tutorial for MockupDB here

Enrique answered 21/5, 2019 at 19:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.