我希望能够设置一个模拟,允许我在应用内置dict
方法时返回一些内容。
我尝试使用__iter__
无济于事。我似乎无法得到任何东西,只有一本空字典:
import mock
mocked_object = mock.MagicMock()
mocked_object.__iter__.return_value = [1, 2, 3]
dict(mocked_object)
# {}
答案 0 :(得分:3)
如果给出了位置参数并且它是映射对象,则使用与映射对象相同的键值对创建字典。否则,位置参数必须是可迭代对象。 iterable中的每个项目本身都必须是具有两个对象的可迭代项。每个项目的第一个对象成为新词典中的一个键,第二个对象成为相应的值。
MagicMock
个对象公开一个keys
方法只是因为是模拟对象,所以dict()
会认为它们是映射对象。不幸的是,如果我们希望在dict
调用模拟成为具有预定义键值的字典,那么使用这种方式有点复杂。以下示例显示如何使用映射对象协议实现dict
到预定义字典的转换:
>>> m = MagicMock()
>>> d = {"a":"A", "b":"B", "c":"C"}
>>> m.keys.return_value.__iter__.return_value = ["a", "b", "c"]
>>> m.__getitem__.side_effect = ["A","B","C"]
>>> dict(m)
{'a': 'A', 'c': 'C', 'b': 'B'}
>>> #Little bit generic
>>> m.keys.return_value.__iter__.return_value = d.keys()
>>> m.__getitem__.side_effect = lambda k:d[k]
>>> dict(m)
{'a': 'A', 'c': 'C', 'b': 'B'}
两者都有点难以阅读,在我们的测试中,我们想要一些更简单的阅读。
要引导dict
使用迭代器代替映射,我们只需从模拟中移除keys
方法并设置__iter__.return_value
:
>>> del m.keys
>>> m.__iter__.return_value = [("a","A"),("b","B"),("c","C")]
>>> dict(m)
{'a': 'A', 'c': 'C', 'b': 'B'}
>>> #Little bit generic
>>> m.__iter__.return_value = d.items()
>>> dict(m)
{'a': 'A', 'c': 'C', 'b': 'B'}
恕我直言,这是一种简单而简洁的方法来设置模拟并从dict
调用中获取预定义的字典。
答案 1 :(得分:2)
实际上我觉得你需要这样做:
mocked_object.keys.return_value.__iter__.return_value = [1, 2, 3]
这样,dict方法将为您提供一个包含这些键的对象,以及getattr(mocked_object, '1')
(因此,另一个模拟方法)的结果作为值。我想如果你想要对结果进行更多控制,你也可以通过模拟keys()
方法做你想做的事。