Feature: mongodb as replica set (single node)
What are you trying to do?
Unit testing of Mongodb transactions.
Why should it be done this way?
mongomock can often be used in unit testing of mongodb-related functionality. It's faster and easier than using docker containers for such tests. But perhaps one of the most important scenarios in which mongomock is not applicable is testing the functionality using MongoDB transactions. At the moment, transaction mocking is not implemented in mongomock. But even if support for this was implemented there, such sensitive functionality (using transactions) would like to be checked "naturally". But as you know, transactions are possible only for replica sets, which the default MongoDB container is not. It is possible to configure mongodb as a replicaset (although with one node, but I think this is not critical for testing).
If you find this functionality useful here in the public, I can provide a PR (either as a separate Mongodb container, or extend the current MongoDbContainer with configuration options). What do you think about it?
that would be great! also would be cool to have streaming, i think also only available with replica sets.
mongodb replica set can be set with mongo_container.with_command("--replSet=rs"). but it makes it impossible to set since auth is forced internally and replica set with auth requires a key File. it would be great if the auth is optional.
there is a work around to it
@fixture(autouse=True, scope="session")
def init_testcontainers():
mongo_container = DockerContainer("mongo:6.0.7")
mongo_bind_port = randint(a=30000, b=40000)
mongo_container.with_name("python_testing_mongodb")
mongo_container.with_bind_ports(container=mongo_bind_port, host=mongo_bind_port)
mongo_container.with_command(f"--port={mongo_bind_port} --replSet=rs")
mongo_container.start()
settings().connection_string = f"mongodb://localhost:{mongo_bind_port}/?replicaSet=rs"
exit_code, _ = mongo_container.exec("mongosh --quiet --eval=\"rs.initiate({_id:\'rs\',members:[{_id:0,host:\'localhost:%s\'}]})\" mongodb://localhost:%s" % (mongo_bind_port, mongo_bind_port))
if exit_code != 0:
raise RuntimeError("replica set didn't get setup properly")
yield
mongo_container.stop()
@naolaregaqena can you comment with an example of using the streams for something? this way i can add a test to the pull request for this feature and add it to the library.
@alexanderankin stream also works too, you could use motor like so
async def watch_users():
async with db.users.watch() as users_stream:
async for user in users_stream:
print(user)
Linking the .NET implementation of WithReplicaSet():
https://github.com/testcontainers/testcontainers-dotnet/pull/1196