关于单元测试:在python中模拟字典

Mocking Dictionary in python

我对一般的修补/模拟,尤其是在Python中是陌生的。我正在尝试修补将在测试用例中使用以下方法访问的dict

1
2
3
obj = Foo(None)
with patch.dict(obj.bar.items_dict,{TEST_DIR + '/Transparent.gif', data}):
    output = obj.create_css_for_imgs()

但我得到以下错误。请理解FOO的__init__()功能默认为bar None

attributeError:"nonetype"对象没有"items"属性

课程如下:

1
2
3
4
5
6
7
8
class Foo(object):
    def __init__(self, barVal):
        self.bar = barVal

class Bar():
    def __init__(self, val)
        self.items_dict = {}
        self._load(val)


不确定您的案件中是否需要patchpatch更多的en用于"模拟"模块的功能。您可以使用Mock对象创建用于测试的结构(使用"模拟"方法和属性)。

First of all, I think you got the error because you sent None to
constructor. But NoneType doesn't have items_dict property.

这里有一个小例子可以帮助您:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from mock import Mock

class Foo(object):

    def __init__(self, bar_val):  # type: (Bar) -> None
        self.bar = bar_val

    def get_bar_items_dict(self):  # type: () -> dict
        # just example - return items_dict of Bar object
        return self.bar.items_dict

    def create_css_for_imgs(self):  # type: () -> str
        return 'example'


class Bar(object):

    def __init__(self):
        self.items_dict = {}
        # other properties...


class TestExample(TestCase):

    def test_create_css_for_imgs(self):
        # create Mock instead Bar object and say that items_dict isn't empty dict
        bar = Mock(items_dict={'custom': 'dict'})
        # foo.bar will be 'Mock' object
        foo = Foo(bar)
        # check result of 'create_css_for_imgs' Foo object
        self.assertEqual(
            foo.create_css_for_imgs(),
            'example'
        )

        # check result of foo.bar.items_dict
        self.assertDictEqual(
            foo.get_bar_items_dict(),
            {'custom': 'dict'}
        )

让我们总结一下。你得到错误是因为你试图得到None类型的items_dict(看起来像:a = None a.items_dict)。您可以创建任何用于测试的对象(使用"mocked"方法和属性),而无需对原始类进行"修补"。例子:

1
2
3
4
5
6
7
one = Mock(one_propery=1)
two = Mock(one=one)
three = Mock(two=two)
three.my_method.return_value = [1, 2, 3]
# check our object
print three.two.one.one_propery # 1
print three.my_method() # [1, 2, 3]

在某些情况下,我们需要"模拟"类的方法(例如对于组测试)。在这种情况下,您可以使用patch

1
2
3
4
5
6
7
8
9
    mocked_create = mock.patch(
        'your_pack.your_module.Foo.create_css_for_imgs',
        return_value='changed example'
    )
    # change 'example' to 'changed example'
    mocked_create.start()
    foo = Foo(Bar())
    print foo.create_css_for_imgs()  # 'changed example'
    mocked_create.stop()

希望这有帮助。