简体   繁体   中英

Python Mock not correctly setting return value

I am attempting to build unit tests and have been using mock, However upon using two patch statements, I was not able to set the proper return values.

@patch('pulleffect.lib.google.gcal_helper.validate_and_refresh_creds')
@patch('pulleffect.lib.google.gcal_helper.get_google_creds')
def test_get_calendar_list_for_gcalhelper_without_credentials(self, 
                                                              mock_get_google_creds, 
                                                              mock_validate_and_refresh_creds):
    mock_validate_and_refresh_creds = "redirect"
    mock_get_google_creds = "credentials"
    credentials = pulleffect.lib.google.gcal_helper.get_calendar_list("name","widget")
    assert b'redirect' in credentials

however the assert fails and instead of the expected string redirect I instead get

<MagicMock name = "validate_and_refresh_creds() id = 14054613955344>

I was wondering what is necessary to have redirect returned instead. I have not encountered this issue when only patching a single method.

I was able to fix the issue of

<MagicMock name = "foo()" id = number>

incorrectly appearing by replacing my earlier code with:

from mock import MagicMock

def test_get_calendar_list_for_gcalhelper_without_credentials(self):

    rtn = { "redirect": "/gcal/authenticate"}       
    pulleffect.lib.google.gcal_helper.validate_and_refresh_creds = MagicMock(name = "sup", return_value  = rtn)
    pulleffect.lib.google.gcal_helper.get_google_creds = MagicMock(name = "sup2", return_value  = "redirect")
    credentials = pulleffect.lib.google.gcal_helper.get_calendar_list("name","widget")
        assert b'redirect' in credentials

this allowed the return values to be properly set.

mock_get_google_creds and mock_validate_and_refresh_creds created with patch decorator are ordinary mock objects (Mock or MagicMock). Direct assignment is not the correct way to set return values. Use return_value attribute:

mock_validate_and_refresh_creds.return_value = "redirect"

Also you can set it during patching :

patch takes arbitrary keyword arguments. These will be passed to the Mock (or new_callable) on construction.

@patch('pulleffect.lib.google.gcal_helper.get_google_creds', return_value="redirect")

I recommend you to use this solution. You should move your functions to helper class and instead static methods user class methods, because it's possible to mock class in this way.

class GCallHelper(object):
     @classmethond
     def validate_and_refresh(cls):
        ...
        return result

def test_get_calendar_list_for_gcalhelper_without_credentials(self):
    with patch('pulleffect.lib.google.gcal_helper') as mocked_gcal:
        mocked_gcal.return_value.validate_and_refresh_creds.return_value = 'redirect'
        mocked_gcal.return_value.get_google_creds.return_value = 'credentials'

        credentials = pulleffect.lib.google.gcal_helper.get_calendar_list("name","widget")
        assert b'redirect' in credentials

ps And you forgot 'return_value' in your example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM