Skip to content
Small library for mocking pymongo collection objects for testing purposes
Python Makefile
Branch: develop
Clone or download
Type Name Latest commit message Commit time
Failed to load latest commit information.
mongomock Do not modify inserted documents, except for the _id. Oct 24, 2019
tests Do not modify inserted documents, except for the _id. Oct 24, 2019
.travis.yml Test mongomock on Python 3.8 as well. Oct 23, 2019
LICENSE Initial version Mar 14, 2012 When releasing ot Pypi, distribute the sdist as well. Jun 1, 2019
Makefile add Makefile Dec 25, 2013
Missing_Features.rst Add raw batch BSON operations as not implemented (missing) features. Oct 23, 2019
README.rst Implement the $facet operator. (#563) Sep 17, 2019
requirements.txt Introduce a patch method, for an easy replacement of pymongo by mongo… Oct 13, 2018
setup.cfg Added Python 3.5 trove classifier. Jun 29, 2016
tox.ini Test mongomock on Python 3.8 as well. Oct 23, 2019


Travis CI build PyPI package PyPI license PyPI wheel status

What is this?

Mongomock is a small library to help testing Python code that interacts with MongoDB via Pymongo.

To understand what it's useful for, we can take the following code:

def increase_votes(collection):
    for document in collection.find():
        collection.update_one(document, {'$set': {'votes': document['votes'] + 1}})

The above code can be tested in several ways:

  1. It can be tested against a real mongodb instance with pymongo.
  2. It can receive a record-replay style mock as an argument. In this manner we record the expected calls (find, and then a series of updates), and replay them later.
  3. It can receive a carefully hand-crafted mock responding to find() and update() appropriately.

Option number 1 is obviously the best approach here, since we are testing against a real mongodb instance. However, a mongodb instance needs to be set up for this, and cleaned before/after the test. You might want to run your tests in continuous integration servers, on your laptop, or other bizarre platforms - which makes the mongodb requirement a liability.

We are left with #2 and #3. Unfortunately they are very high maintenance in real scenarios, since they replicate the series of calls made in the code, violating the DRY rule. Let's see #2 in action - we might write our test like so:

def test_increase_votes():
    objects = [dict(...), dict(...), ...]
    collection_mock = my_favorite_mock_library.create_mock(Collection)
    for obj in objects:
        collection_mock.update_one(document, {'$set': {'votes': document['votes']}})

Let's assume the code changes one day, because the author just learned about the '$inc' instruction:

def increase_votes(collection):
    collection.update_many({}, {'$inc': {'votes': 1}})

This breaks the test, although the end result being tested is just the same. The test also repeats large portions of the code we already wrote.

We are left, therefore, with option #3 -- you want something to behave like a mongodb database collection, without being one. This is exactly what this library aims to provide. With mongomock, the test simply becomes:

def test_increase_votes():
    collection = mongomock.MongoClient().db.collection
    objects = [dict(votes=1), dict(votes=2), ...]
    for obj in objects:
        obj['_id'] = collection.insert_one(obj).inserted_id
    for obj in objects:
        stored_obj = collection.find_one({'_id': obj['_id']})
        stored_obj['votes'] -= 1
        assert stored_obj == obj # by comparing all fields we make sure only votes changed

This code checks increase_votes with respect to its functionality, not syntax or algorithm, and therefore is much more robust as a test.

If the code to be tested is creating the connection itself with pymongo, you can use mongomock.patch:

@mongomock.patch(servers=(('', 27017),))
def test_increate_votes_endpoint():
  objects = [dict(votes=1), dict(votes=2), ...]
  client = pymongo.MongoClient('')
  ... verify client.db.collection

Important Note About Project Status & Development

MongoDB is complex. This library aims at a reasonably complete mock of MongoDB for testing purposes, not a perfect replica. This means some features are not likely to make it in any time soon.

Also, since many corner cases are encountered along the way, our goal is to try and TDD our way into completeness. This means that every time we encounter a missing or broken (incompatible) feature, we write a test for it and fix it. There are probably lots of such issues hiding around lurking, so feel free to open issues and/or pull requests and help the project out!

NOTE: We don't include pymongo functionality as "stubs" or "placeholders". Since this library is used to validate production code, it is unacceptable to behave differently than the real pymongo implementation. In such cases it is better to throw NotImplementedError than implement a modified version of the original behavior.


When submitting a PR, please make sure that:

  1. You include tests for the feature you are adding or bug you are fixing. Preferably, the test should compare against the real MongoDB engine (see examples in tests for reference).
  2. No existing test got deleted or unintentionally castrated
  3. The travis build passes on your PR.

To download, setup and perfom tests, run the following commands on Mac / Linux:

git clone
pip install tox
cd mongomock

Branching model

The branching model used for this project follows the gitflow workflow. This means that pull requests should be issued against the develop branch and not the master branch. If you want to contribute to the legacy 2.x branch than your pull request should go into the support/2.x branch.


Mongomock has originally been developed by Rotem Yaari, then by Martin Domke < It is currently being developed and maintained by Pascal Corpet .

Also, many thanks go to the following people for helping out, contributing pull requests and fixing bugs:

  • Alec Perkins
  • Alexandre Viau
  • Austin W Ellis
  • Andrey Ovchinnikov
  • Arthur Hirata
  • Baruch Oxman
  • Corey Downing
  • Craig Hobbs
  • Daniel Murray
  • David Fischer
  • Diego Garcia
  • Dmitriy Kostochko
  • Drew Winstel
  • Eddie Linder
  • Edward D'Souza
  • Emily Rosengren
  • Eugene Chernyshov
  • Grigoriy Osadchenko
  • Israel Teixeira
  • Jacob Perkins
  • Jason Burchfield
  • Jason Sommer
  • Jeff Browning
  • Jeff McGee
  • Joël Franusic
  • Jonathan Hedén
  • Julian Hille
  • Krzysztof Płocharz
  • Lyon Zhang
  • Marc Prewitt
  • Marcin Barczynski
  • Marian Galik
  • Michał Albrycht
  • Mike Ho
  • Nigel Choi
  • Omer Gertel
  • Omer Katz
  • Papp Győző
  • Paul Glass
  • Scott Sexton
  • Srinivas Reddy Thatiparthy
  • Taras Boiko
  • Todd Tomkinson
  • Zachary Carter
  • catty (ca77y _at_
  • emosenkis
  • hthieu1110
  • יppetlinskiy
  • pacud
  • tipok
  • waskew (waskew _at_
  • jmsantorum (jmsantorum [at] gmail [dot] com)
  • lidongyong
You can’t perform that action at this time.