Python Unit Testing – Mocking Imports for CI/CD

continuous integrationimportmockingpythonunit testing

I have a project written in python that I would like to create unit tests on.

This project has a dependency on a database project which is a sort of abstraction layer to data connections.

The issue with this db project is that it's huge! So when I want to run the unit tests as part of a continuous integration pipeline I have to download it each time and install it with pip and all the requirements etc.

Ignoring the refactoring of the project which is to come, and knowing that the unit tests for the main project only concern functions within itself and I will be mocking any database queries:

Is there a way of effectively mocking the imports as I can of course mock the classes from the database project but I will still have the import db_project for example in the code so I will still have to pull this project down surely?

How can I remove these dependencies if it is even possible, knowing I am going to mock any methods that are used anyway?

Best Answer

  • Create an abstraction layer that wraps whatever functionality you need from the data base.

  • Create a trivial mock implementation to be used in unit tests. Create a second almost as trivial implementation that just delegates every call to the real call.

  • In your code under test, import the abstraction layer, not the data base module.

  • Orchestrate things so that the first implementation is handed to your class during tests, and the second implementation during production.

In other words, you have rediscovered the need for dependency injection. That is good news! DI is a solved problem, in fact a best practice, and having understood through your own experience why it is a good idea, you now fully comprehend how good an idea it is. (Personally, I find this way of learning things works much better than reading them in a textbook with some anemic, unconvincing example.)