模拟对象并修补相关函数

Mocking an object and patching associated functions

我有一个创建 Widget 的简单应用程序,并在其中创建了一个 Env 对象。初始化 Env 对象需要大量外部调用,而这些调用对于我正在测试的函数来说不是必需的,因此我只想模拟整个对象(或 init)。但是,我想将 get_parents 函数修补为 return 特定数据以进行测试。我无法弄清楚如何修补它。这是我的 类:

env.py:

class Env(object):
    def __init__(self):
        # Lots of external calls that are not needed for
        # this specific test
        pass

    def get_parents(self):
        return ['moms']

widget.py

from env import Env

class Widget(object):
    def __init__(self):
        self.env = Env()

    def display_parents(self):
        return ','.join(self.env.get_parents())

我正在尝试设置测试以修补初始对象创建和我正在尝试修补的函数的 return 值。这模拟了对象,但没有 return 正确的值:

tests/test_widget.py

@patch('widget.Env.get_parents', return_value=['moms,pops'])
@patch('widget.Env')
def test_widget(mock_env, mock_get_parents):
    widget = Widget()
    assert widget.display_parents() == 'moms,pops' # Fails

我试过用这种方式修补和模拟,但 get_parents 函数甚至没有被调用:

from widget import Widget
from unittest.mock import patch

@patch('widget.Env.get_parents', return_value=['moms,pops'])
@patch('widget.Env')
def test_widget(mock_env, mock_get_parents):
    widget = Widget()
    widget.display_parents()
    assert mock_get_parents.called

您的 Env 补丁覆盖了您的 mock_get_parents。只需修补 Env 并适当修改其属性;这正是 Mock 对象如此灵活的原因!

@patch('widget.Env')
def test_widget(mock_env_class):
    mock_env_class.return_value.get_parents.return_value=['moms,pops']
    widget = Widget()
    widget.display_parents()
    assert mock_env_class.return_value.get_parents.call_count == 1