ling
ling

Reputation: 185

Pytest Monkeypatch package native instance method

I am trying to use pytest and monkeypatch to unit test a method that has uses a third party data integration package.

Here is some example pseudo code:

from third_party.data_integration import Account

def fetch_data():
    account_id = "123"
    account_token = "234"

    account = Account(account_id, account_token)
    account.download('path')
    return True

I am hoping to do some like blow in my test file to monkeypatch the download instance function:

def test_fetch_data(monkeypatch):

    def download():
        return '123'

    with monkeypatch.context() as m:
         m.setattr('third_party.data_integration.Account.download', download)
         assert fetch_data() == True

Obviously, m.setattr('third_party.data_integration.Account.download', download) would only work for static method instead of instanced method or class method. What is the best practice to do test like this to monkey patch a third party native package instance method?

Upvotes: 0

Views: 827

Answers (1)

rdas
rdas

Reputation: 21305

Since you're calling the constructor of the Account class & the method you want to mock is an attribute of the return value of that constructor, you need to mock the return value of the constructor and then monkeypatch the download attribute of the mock.

Here's how I would do it:

@mock.patch('third_party.data_integration.Account')
def test_fetch_data(mock_account):

    def download():
        return '123'
    acc = MagicMock()
    acc.download = download
    mock_account.return_value = acc
    assert fetch_data() == True

Upvotes: 1

Related Questions