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 该列表按顺序排列。
我有一个更改对象属性的对象方法。另一种方法(我正在尝试测试的方法)多次调用第一个方法,然后使用修改后的属性。如何在明确说明第一种方法如何更改该属性的同时测试第二种方法?
例如:
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 该列表按顺序排列。