Python - 用多个值模拟一个对象的属性?

Python - Mocking an object's attribute with multiple values?

我有一个更改对象属性的对象方法。另一种方法(我正在尝试测试的方法)多次调用第一个方法,然后使用修改后的属性。如何在明确说明第一种方法如何更改该属性的同时测试第二种方法?

例如:

def method_to_test(self):
    output = []
    for _ in range(5):
        self.other_method()
        output.append(self.attribute_changed_by_other_method)
    return output

我想指定 attribute_changed_by_other_method 由于 other_method 而变成的一些特定值(真正的 other_method 使用概率来决定如何更改 attribute_changed_by_other_method) .

我猜最好的方法是 "mock" 属性 attribute_changed_by_other_method 这样每次读取值时它都会返回我的规范的不同值。我似乎无法找到如何做到这一点。我看到的另一个选择是确保 other_method 被模拟以每次都以定义的方式更新属性,但我不知道这样做的特别干净的方法。有人可以建议一个合理的方法来解决这个问题吗?非常感谢。

您实际上可以做的是将 flexmock 用于 other_method。你可以用 flexmock 做的是在你的 class 实例上设置一个模拟。这是一个如何使用它的例子:

class MyTestClass(unittest.TestCase):
    def setUp(self):
        self.my_obj = MyClass()
        self.my_obj_mock = flexmock(self.my_obj)

    def my_test_case(self):
        self.my_obj_mock.should_receive('other_method').and_return(1).and_return(2).and_return(3)
        self.my_obj.method_to_test()

所以,这里发生的是,在您的 MyClass 实例上,您正在从 self.my_obj 中创建一个 flexmock 对象。然后在您的测试用例中,您声明当您调用 method_to_test 时,您应该收到 other_method,并且每次调用它应该分别 return 1, 2, 3

此外,如果您仍然想知道如何模拟 attribute_changed_by_other_method,您可以使用 Mock 的 PropertyMock:

希望这对您有所帮助。让我知道进展如何!

对于仍在寻找直接答案的任何人,可以按照已接受答案的建议使用 PropertyMock 轻松完成。这是一种方法。

from unittest.mock import patch, PropertyMock


with patch("method_your_class_or_method_calls", new_callable=PropertyMock) as mock_call:
        mock_call.side_effect = [111, 222]
        class_or_method()

该修补方法的每个后续调用都将 return 该列表按顺序排列。