Python Mock未正确设置返回值

1 投票
3 回答
1703 浏览
提问于 2025-04-18 08:22

我正在尝试编写单元测试,并且一直在使用模拟(mock)。不过,当我使用两个补丁语句时,我无法设置正确的返回值。

@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

但是,断言(assert)失败了,我得到的结果不是我期望的字符串redirect,而是

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

我想知道要怎么做才能返回redirect这个值。我在只补丁一个方法时没有遇到这个问题。

3 个回答

0

我建议你使用这个解决方案。你应该把你的函数放到一个辅助类里,而不是用静态方法,应该用类的方法,因为这样可以更方便地进行模拟测试。

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

另外,你在例子里忘记加'return_value'了。

1

mock_get_google_credsmock_validate_and_refresh_creds 是用补丁装饰器创建的普通模拟对象(Mock 或 MagicMock)。直接赋值不是设置返回值的正确方法。应该使用 return_value 属性:

mock_validate_and_refresh_creds.return_value = "redirect"

你也可以在 打补丁 的时候设置返回值:

patch 可以接收任意的关键字参数。这些参数会在创建模拟对象(Mock 或 new_callable)时传入。

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

我解决了这个问题,

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

是通过把之前的代码换成:

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

这样就能正确设置返回值了。

撰写回答