Home > database >  How to mock reponse of instantiated mocked object with python pytest
How to mock reponse of instantiated mocked object with python pytest

Time:03-14

I'm trying to mock a function that calls the sendgrid API. I want to mock the API library but can't work out where I'm going wrong.

Function which calls the 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

my bad test:

@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": "[email protected]",
                "contact_name": None,
                }
        result = mailing_list_signup(data)

        assert result == response

Pytest tells me the test failed with the following message:

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')

CodePudding user response:

Because a return value of a callable is being mocked, the return value should be set on a callable and not an attribute.

change sendgridAPI.client.marketing.contacts.put.return_value = response to sendgridAPI.client.marketing.contacts.put().return_value = response

  • Related