Introducing Pytest FastAPI Dependencies

Peter Kogan
3 min readMay 23, 2022

Recently, I was working on a FastAPI project. Things were going great until I had to do some unit testing to ensure that the functionality behaves the way I intended: FastAPI does provide a rich TestClient, but I was looking to do something specific — replace a dependency function.

FastAPI provides the ability to replace dependency functions like so:

However, this is not native to Pytest — if you copy & paste this code as is to your test directories, you would be getting some unexpected behavior since your override would affect other tests and modules. This happened to developers here and here.

If only Pytest had a standard way of setup and cleanup for testing… fixtures of course!

From here, the road ahead was trivial: I’ll create a fixture that would make the dependency replacement natural.

Better yet, I’ll make an open-source pytest plugin out of it, so everyone can use it.

If you care about the implementation details — read this section. If not, you can jump to the next section where I show the usage of this plugin.

The first thing we need is a clean way of setting and un-setting overrides. A Python context manager is an obvious solution and one that was suggested in this stack overflow answer. The code is:

The code above is pretty trivial, we get a FastAPI app and a dictionary of overrides where the key is the old function and the value is the replacement function. When we enter the context, the dictionary replacements are applied and when we exit the context, they are removed and the previous functions are restored.

Next, we need to convert this context manager into something that is usable in Pytest, i.e. a fixture:

This code needs a bit more explaining.

Let’s start with the fastapi_dep function: it defines a fixture with the same name. There are two ways to use the fixture: with or without parameters.

If we use the fixture without parameters, then we would get back the FixtureDependencyOverrider class, which can be used directly in the test. See test_main.py for a usage example in the section below.

If we want to make our test body cleaner, we can provide the FastAPI and the overrides directly to the fixture, so the context manager can be created there. The matching example is shown later in test_main_indirect.py.

To use the library, install it via pip:

pip install pytest-fastapi-deps

Then, if your code has an endpoint like this which uses depends:

You can add tests to it like so:

Note the fastapi_dep fixture and the context manager — you create it using the FastAPI app and provide it with a dictionary of replacement functions.

The moment you step out of the context, the overrides are removed your code returns to its normal behavior — other tests won’t be affected.

The above example is very expressive in terms of code. If you want a more minimal signature inside your test body, you can use the following syntax alternative, which has the same effect:

The making of the project took me a few hours and that includes everything — the coding itself, testing, documenting, and publishing to PyPI.

Feel free to use this plugin and spread the word.

If you have any comments or issues, you can comment below or open an issue on the project homepage.

--

--