Fastapi: [QUESTION] How to test BackgroundTasks?

Created on 2 Apr 2020  路  5Comments  路  Source: tiangolo/fastapi

I'm wondering if there is a recommended way to stub out BackgroundTasks in unit tests? If I'm running a test for an endpoint I definitely don't want to run any BackgroundTasks that endpoint is creating (e.g. sending emails).

The way I'm doing this right now which seems to work is by creating a wrapper dependency so I can then override it like any other custom dependency. Like this:

def tasks(background_tasks: BackgroundTasks) -> BackgroundTasks:
    """ Just a wrapper dependency for BackgroundTasks """
    return background_tasks

@router.post("/")
def my_endpoint(background_tasks: BackgroundTasks = Depends(tasks)):
    tasks.add_task(...)

Then in my conftest.py I do something like:

@pytest.fixture
def mock_backround_tasks(mocker):
    """ The mocked background_tasks dependency """
    return mocker.MagicMock(autospec=BackgroundTasks)

app.dependency_overrides[tasks] = lambda: mock_backround_tasks

This feels a bit clunky, I'm wondering if there is a better way to do something like this and if you might add a Testing BackgroundTasks section to the docs with your recommendation?

question

Most helpful comment

In case people want an example:

    with patch("fastapi.BackgroundTasks.add_task") as mock:

        def side_effect(*args, **kwargs):
            <do something>

        mock.side_effect = side_effect

All 5 comments

I encountered the same problem and I use mocker to patch task

 def test_success(self, client, mocker):
        from api.dependences import feedback
        mocker.patch.object(feedback, "send_email_task")
        response = client.post('/endpoint',  json=data)
        assert feedback.send_email_task.called is True

I thought about doing it that way, but how can you be sure the background task is called immediately? Isn鈥檛 it asynchronous? I wouldn鈥檛 want a case where sometimes the test fails because the function hasn鈥檛 been called yet

Yeah, I think Python's own unittest.mock might be useful here: https://docs.python.org/3/library/unittest.mock.html

You could mock the entire BackgroundTasks class in your tests.

And if you want to test the actual functions for the background tasks, you can test them as functions directly too, without having to go through the process of adding them as background tasks.

Assuming the original issue was solved, it will be automatically closed now. But feel free to add more comments or create new issues.

In case people want an example:

    with patch("fastapi.BackgroundTasks.add_task") as mock:

        def side_effect(*args, **kwargs):
            <do something>

        mock.side_effect = side_effect
Was this page helpful?
0 / 5 - 0 ratings