python unittest:模拟类似dict的对象

时间:2019-03-01 18:28:28

标签: python python-unittest

我正在尝试执行以下操作:

def test_fn(self):
    cool_dict = {}
    blah = Mock(spec=DictField, wraps=cool_dict)
    blah['key'] = 'val'
    print(cool_dict))
    return False

基本上,我想确保blah发生DictField发生的任何事情,但我希望blah发生的任何事情实际上发生在cool_dict ,因此我可以断言它具有某种状态。

我该怎么做?上面的代码失败:

FAILED (errors=1)

Error
Traceback (most recent call last):
  File "C:\Program Files\Python 3.5\Lib\unittest\case.py", line 59, in testPartExecutor
    yield
  File "C:\Program Files\Python 3.5\Lib\unittest\case.py", line 605, in run
    testMethod()
  File "C:\Users\danie01.AD\PycharmProjects\component\component\Default\Functional\pam_team_management\test\test_team_create.py", line 23, in test_populate_info_page
    blah['key'] = 'val'
TypeError: 'Mock' object does not support item assignment

我还尝试了MagicMock

def test_populate_info_page(self):
    cool_dict = {}
    blah = MagicMock(spec=DictField, wraps=cool_dict)
    blah['key'] = 'val'
    print(cool_dict)
    return False

没有失败,但是cool_dict仍然是{}

1 个答案:

答案 0 :(得分:1)

在 Python 中,您还可以使用 魔法方法,它们是类的内置方法。对于 dict 对象,您需要覆盖 __getitem__()__setitem__() 魔术方法。

例如,当您执行 blah['key'] = 'var' 语句时,它实际上是在调用 blah.__setitem__('key', 'var')。因此,您需要模拟这两个魔术方法,然后检查这些模拟方法的状态。

以下是我如何尝试您所说的内容的示例:

>>> cool_dict = {'key': 'val'}
>>> blah = Mock()
>>> blah.__getitem__ = Mock()
>>> blah.__getitem__.side_effect = cool_dict.__getitem__
>>> blah['key']
'val'
>>> blah.__getitem__.assert_called() # No assertion raised, which means that it was called
>>> 

所以在这个例子中,'blah' 对象的 __getitem__() 方法是你将要使用 Mock() 来模拟的东西,然后你创建了一个副作用:它触发__getitem__() 上的相同 cool_dict 函数。在它被调用之后,您可以随后检查该 Mock 以查看它是否被调用以及它被调用了什么。有关更多上下文,请参阅 Mocking Magic Methods