As head of engineering professionally and as a contributor to Open Source projects, I am involved in several WebApp projects, where I put a large emphasis on code quality, smooth CI/CD pipelines as part of my dedication to DevOps principles. Some of the projects involves interactions with S3 storage via the Minio package for python. Writing unit tests for functions using the
Minio client is essential and should not involve interactive with an actual S3 storage service. Against my expectations, I could not find any
pytest plugin that mocks
After writing and reviewing some unit tests for interactions with the minio client, I though I had a good concept for a first version of a pytest plugin, that provides a fixture called
minio-mock that mocks
Minio() client created after the declaration of the minio-mock fixture. The result was the package
pytest-minio-mock that I published on pypi.org under: https://pypi.org/project/pytest-minio-mock/. and you can find the source code under: https://github.com/oussjarrousse/pytest-minio-mock.
The plugin is small, not fancy and is not yet fully featured, but it is useful for the basics, and I hope you find it useful to.
The Plugin Design
The plugin code resides in the plugin.py module: https://github.com/oussjarrousse/pytest-minio-mock/blob/main/pytest_minio_mock/plugin.py where the main fixture minio-mock is defined as:
def minio_mock(mocker, minio_mock_servers):
client = MockMinioClient(*args, **kwargs)
patched = mocker.patch.object(Minio, "__new__", new=minio_mock_init)
mocker fixture is used to patch the Minio class and override the
__new__() function, and replace it with the
minio_mock_init() function that is defined within the fixture body.
When a Minio object is created, the function
minio_mock_init() is called that creates a instance of the
MockMinioClient class, and return the newly created instance… as in:
# will call __new__() of Minio that has been mocked to call minio_mock_init()
client = Minio()
assert isinstance(client, MockMinioClient)
The MockMinioClient class provide an interface that is identical to the Minio class, but instead of interacting with an actual server, it interacts internally with a Server object that stores objects in memory.
The Server object provides persistency of buckets and objects between consecutive initiations of Minio instances. If the server object was destroyed, buckets and objects will also be destroyed and a consecutive initiation of Minio() client will not be able to retrieve buckets or objects.
The plugin is still at its early days and I am sure many features are still missing.
If you find it useful give the github repository a star, so that I know you are out there.
Some additional info:
Download stats of pytest-minio-mock: https://pypistats.org/packages/pytest-minio-mock
Reverse dependency of pytest-minio-mock: https://www.wheelodex.org/projects/pytest-minio-mock/rdepends/