0

在我的 FastAPI 应用程序中,我想模拟background_tasks.add_task以便可以监视对它的调用。

但是,我不知道如何才能访问它。

4

1 回答 1

1

这是一个工作示例。创建两个文件:

主文件

from fastapi import FastAPI, BackgroundTasks

app = FastAPI()

def write_notification(email: str, message=""):
    with open("log.txt", mode="w") as email_file:
        content = f"notification for {email}: {message}"
        email_file.write(content)


@app.post("/send-notification/{email}")
async def send_notification(email: str, background_tasks: BackgroundTasks):
    background_tasks.add_task(write_notification, email, message="some notification")
    return {"message": "Notification sent in the background"}

test_main.py

import pytest
from fastapi.testclient import TestClient
from fastapi import BackgroundTasks
from requests import Response

from main import app, write_notification
from unittest.mock import mock_open


@pytest.fixture
def client():
    return TestClient(app)


def test_send_notification(
    client, mocker,
):
    mock_file_open = mocker.patch(
        "main.open", new=mock_open()
    )  # https://docs.python.org/3/library/unittest.mock.html#mock-open
    spy = mocker.spy(BackgroundTasks, "add_task")

    r: Response = client.post("/send-notification/f00@example.com")

    # validate the HTTP response
    assert r.status_code == 200
    assert r.json() == {"message": "Notification sent in the background"}

    # validate the add_task call was made
    spy.assert_called_with(
        mocker.ANY,  # add_task() is a method, and as such its first argument is `self`
        write_notification,
        "f00@example.com",
        message="some notification",
    )

    # validate the background task did its job
    assert mocker.call("log.txt", mode="w") in mock_file_open.call_args_list
    handle = mock_file_open()
    handle.write.assert_called_once_with(
        "notification for f00@example.com: some notification"
    )

并安装以下依赖项:

pip install fastapi==0.53.0 pytest==5.4.1 pytest-mock==2.0.0 requests==2.23.0

最后运行 pytest 命令:

pytest test_main.py

解释

  • mocker夹具来自pytest-mock ,在使用 pytest 时非常方便模拟/监视。
  • spy = mocker.spy(BackgroundTasks, "add_task")就是你要找的。

你可以克隆这个gist 来尝试一下。

于 2020-03-29T10:54:03.710 回答