如何使用 python pytest 模拟实例化模拟对象的响应

How to mock reponse of instantiated mocked object with python pytest

我正在尝试模拟一个调用 sendgrid API 的函数。我想模拟 API 库,但不知道哪里出错了。

函数调用 API:

def mailing_list_signup(data: dict):

    email_address = data["email"]
    name = data["contact_name"]

    API_KEY = settings.SENDGRID_API_KEY
    sg = SendGridAPIClient(API_KEY)

    # https://docs.sendgrid.com/api-reference/contacts/add-or-update-a-contact
    data = {
        "contacts": [
            {
                "email": email_address,
                "name": name,
            }
        ]
    }

    response = sg.client.marketing.contacts.put(request_body=data)
    return response

我的考试不好:

@dataclass
class APIResponse:
    status_code: int = 202
    body: bytes = b"example"


@override_settings(SENDGRID_API_KEY='123')
def test_mailing_list_signup():
    response = APIResponse()
    with mock.patch("myapp.apps.base.business.SendGridAPIClient") as sendgridAPI:
        sendgridAPI.client.marketing.contacts.put.return_value = response

        data = {
                "email": "name@example.com",
                "contact_name": None,
                }
        result = mailing_list_signup(data)

        assert result == response

Pytest 告诉我测试失败并显示以下消息:

FAILED myapp/apps/base/tests/test_business.py::test_mailing_list_signup - AssertionError: assert <MagicMock name='SendGridAPIClient().client.marketing.contacts.put()' id='4622453344'> == APIClient(status_code=202, body=b'example')

因为可调用对象的 return 值被模拟,return 值应该设置在可调用对象而不是属性上。

改变 sendgridAPI.client.marketing.contacts.put.return_value = responsesendgridAPI.client.marketing.contacts.put().return_value = response