首页 > 解决方案 > 更改对象补丁以外的其他属性的返回值

问题描述

我有以下单元测试。

class PhoneBook:
    def __init__(self):
        self.numbers: Dict[str, str] = {}

    def add(self, name: str, number: str) -> None:
        self.numbers[name] = number

    def lookup(self, name: str) -> str:
        return self.numbers[name]


class Mobile:
    def __init__(self, phonebook: PhoneBook):
        self.phonebook = phonebook

    def call(self, name: str) -> None:
        number = self.phonebook.lookup(name)
        logging.info(f"Calling {name} on number: {number}")


@mock.patch.object(PhoneBook, "add")
def test_mobile_call(mock_phonebook: PhoneBook):
    # Arrange
    mock_phonebook.lookup.return_value = "123"
    mobile = Mobile(mock_phonebook)
    # Act
    mobile.call("Nick")
    # Assert
    mock_phonebook.lookup.assert_called_with("Nick")

使用补丁注释我希望修补add电话簿的功能/方法。但正如您所看到的,我实际上能够更改lookup方法的返回值并断言它是使用特定值调用的。

标签: pythonunit-testingtestingmockingmonkeypatching

解决方案


这种行为的原因是您实际上并没有调用修补函数 ( Phonebook.add)。你从那个补丁中得到的是一个MagickMock修补函数的对象,但除此之外只是一个通用的模拟。

正在做的事情相当于:

def test_mobile_call():
    # Arrange
    mock_phonebook = MagicMock()
    mock_phonebook.lookup.return_value = "123"
    mobile = Mobile(mock_phonebook)
    # Act
    mobile.call("Nick")
    # Assert
    mock_phonebook.lookup.assert_called_with("Nick")

简而言之,在这种情况下您不需要修补任何东西,因为您要模拟的对象作为参数传递给测试函数。


推荐阅读