Skip to main content
https://img.shields.io/pypi/v/mongomock-ng.svg?style=flat-square https://img.shields.io/github/actions/workflow/status/engFelipeMonteiro/mongomock-ng/lint-and-test.yml?branch=develop&style=flat-square https://img.shields.io/pypi/l/mongomock-ng.svg?style=flat-square https://img.shields.io/codecov/c/github/engFelipeMonteiro/mongomock-ng.svg?style=flat-square

Seeking maintainers

This project is seeking maintainers, see here for more information.

What is this?

Mongomock-ng 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)
    record()
    collection_mock.find().AndReturn(objects)
    for obj in objects:
        collection_mock.update_one(obj, {'$set': {'votes': obj['votes']}})
    replay()
    increase_votes(collection_mock)
    verify()

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-ng, the test simply becomes:

def test_increase_votes():
    collection = mongomock_ng.MongoClient().db.collection
    objects = [dict(votes=1), dict(votes=2), ...]
    for obj in objects:
        obj['_id'] = collection.insert_one(obj).inserted_id
    increase_votes(collection)
    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_ng.patch (NOTE: you should use pymongo.MongoClient(...) rather than from pymongo import MongoClient, as shown below):

@mongomock_ng.patch(servers=(('server.example.com', 27017),))
def test_increate_votes_endpoint():
  objects = [dict(votes=1), dict(votes=2), ...]
  client = pymongo.MongoClient('server.example.com')
  client.db.collection.insert_many(objects)
  call_endpoint('/votes')
  ... 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.

Upgrading to Pymongo v4

The major version 4 of Pymongo changed the API quite a bit. The Mongomock-ng library has evolved to help you ease the migration:

  1. Upgrade to Mongomock-ng v4 or above: if your tests are running with Pymongo installed, Mongomock-ng will adapt its own API to the version of Pymongo installed.

  2. Upgrade to Pymongo v4 or above: your tests using Mongomock-ng will fail exactly where your code would fail in production, so that you can fix it before releasing.

Quick Start

Install with pip:

pip install mongomock-ng

Minimal usage:

import mongomock_ng as mongomock

client = mongomock.MongoClient()
db = client['test_db']
collection = db['test_collection']
collection.insert_one({'name': 'test', 'value': 42})
print(collection.find_one())

Mongomock-ng is a drop-in replacement for pymongo in tests. All operations happen in-memory — no MongoDB server required.

Examples

Example scripts are located in the examples/ directory (see examples). Each file demonstrates a different feature:

  • examples/basic_crud.py — Basic CRUD operations (insert, find, update, delete)

  • examples/filtering.py — Query operators ($gt, $in, $regex, projections, sorting)

  • examples/aggregation.py — Aggregation pipeline ($match, $group, $lookup, $sort)

  • examples/validation.py — Schema validation with $jsonSchema

  • examples/ttl.py — TTL index simulation

Documentation

Detailed documentation is available under the docs/ directory:

Contributing

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 code is auto-formatted (hatch fmt).

  4. The build passes on your PR.

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

$ git clone git@github.com:engFelipeMonteiro/mongomock-ng.git
$ pipx install hatch
$ cd mongomock
$ hatch test

Alternatively, docker-compose can be used to simplify dependency management for local development:

$ git clone git@github.com:engFelipeMonteiro/mongomock-ng.git
$ cd mongomock
$ docker compose build
$ docker compose run --rm mongomock_ng

If you want to run hatch against a specific environment in the container:

$ docker compose run --rm mongomock_ng hatch test -py=3.11 -i pymongo=4

If you’d like to run only one test, you can also add the test name at the end of your command:

$ docker compose run --rm mongomock_ng hatch test -py=3.12 -i pymongo=4 tests/test__mongomock.py::MongoClientCollectionTest::test__insert

NOTE: If the MongoDB image was updated, or you want to try a different MongoDB version in docker-compose, you’ll have to issue a docker compose down before you do anything else to ensure you’re running against the intended version.

Code formatting

All code is automatically formatted with ruff and pull-requests are only accepted if the linter passes without complaints. For an open source project this is the only feasible way to maintain a consistent code base, without having to fight endless code style wars. To invoke the formatter and discover issues run

$ hatch fmt

utcnow

When developing features that need to make use of “now,” please use the libraries utcnow helper method in the following way:

import mongomock_ng
# Awesome code!
now_reference = mongomock_ng.utcnow()

This provides users a consistent way to mock the notion of “now” in mongomock-ng if they so choose. Please see utcnow docstring for more details.

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 then your pull request should go into the support/2.x branch.

Releasing

The version is defined in mongomock_ng/__version__.py as the single source of truth.

The release flow is fully automated via CI:

  1. Update __version__ in mongomock_ng/__version__.py (e.g. ‘7.0.4’)

  2. Update CHANGELOG.md with the same version

  3. Open a PR against develop — on merge, a tag v<version> is created automatically

  4. The tag push triggers a build and publish to PyPI

To build locally for testing:

make build

To undo a mistaken tag:

make delete-tag VERSION=7.0.0

Acknowledgements

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

  • Lucas Rangel Cezimbra

  • 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

  • Xinyan Lu

  • Zachary Carter

  • catty (ca77y _at_ live.com)

  • emosenkis

  • hthieu1110

  • יppetlinskiy

  • pacud

  • tipok

  • waskew (waskew _at_ narrativescience.com)

  • jmsantorum (jmsantorum [at] gmail [dot] com)

  • lidongyong

  • Juan Gutierrez

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mongomock_ng-7.8.1.tar.gz (288.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mongomock_ng-7.8.1-py3-none-any.whl (89.9 kB view details)

Uploaded Python 3

File details

Details for the file mongomock_ng-7.8.1.tar.gz.

File metadata

  • Download URL: mongomock_ng-7.8.1.tar.gz
  • Upload date:
  • Size: 288.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: Hatch/1.17.1 {"ci":true,"cpu":"x86_64","distro":{"id":"noble","libc":{"lib":"glibc","version":"2.39"},"name":"Ubuntu","version":"24.04"},"implementation":{"name":"CPython","version":"3.14.6"},"installer":{"name":"hatch","version":"1.17.1"},"openssl_version":"OpenSSL 3.0.13 30 Jan 2024","python":"3.14.6","system":{"name":"Linux","release":"6.17.0-1020-azure"}} HTTPX2/2.7.0

File hashes

Hashes for mongomock_ng-7.8.1.tar.gz
Algorithm Hash digest
SHA256 a0d8002a111d79da2df03187b1a6ba429b9bc44f2f2db89e9fdc9000584bd5a3
MD5 3dd53a3936a682cedfd93f25a4c4f865
BLAKE2b-256 4adc9d52ed7b206628eddc9f21e3842b4bba33da3c1c713377b66e0765fdca99

See more details on using hashes here.

File details

Details for the file mongomock_ng-7.8.1-py3-none-any.whl.

File metadata

  • Download URL: mongomock_ng-7.8.1-py3-none-any.whl
  • Upload date:
  • Size: 89.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: Hatch/1.17.1 {"ci":true,"cpu":"x86_64","distro":{"id":"noble","libc":{"lib":"glibc","version":"2.39"},"name":"Ubuntu","version":"24.04"},"implementation":{"name":"CPython","version":"3.14.6"},"installer":{"name":"hatch","version":"1.17.1"},"openssl_version":"OpenSSL 3.0.13 30 Jan 2024","python":"3.14.6","system":{"name":"Linux","release":"6.17.0-1020-azure"}} HTTPX2/2.7.0

File hashes

Hashes for mongomock_ng-7.8.1-py3-none-any.whl
Algorithm Hash digest
SHA256 11226eccaa65defc102becdd29da9205d8e756f120b51183ede9195edc4936b3
MD5 c5d547718d6080aaa97123f3d350aba1
BLAKE2b-256 8f08e72430bea5b7adb279d494f147d8cfa4a87c028dfe3f9b3a0eb152ec7f63

See more details on using hashes here.

Release history Release notifications | RSS feed

7.11.1

2 files

7.11.0

2 files

7.10.0

2 files

7.9.3

2 files

7.9.2

2 files

7.9.1

2 files

7.9.0

2 files

7.8.3

2 files

7.8.2

2 files

This release

7.8.1 This release

2 files

7.8.0

2 files

7.7.0

2 files

7.6.0

2 files

7.5.14

2 files

7.5.13

2 files

7.5.12

2 files

7.5.11

2 files

7.5.10

2 files

7.5.9

2 files

7.5.8

2 files

7.5.7

2 files

7.5.5

2 files

7.5.4

2 files

7.5.3

2 files

7.5.2

2 files

7.5.1

2 files

7.5.0

2 files

7.4.1

2 files

7.4.0

2 files

7.3.0

2 files

7.2.0

2 files

7.1.1

2 files

7.1.0

2 files

7.0.2

2 files

7.0.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page