python 中的模拟词典

Mocking Dictionary in python

我是 patching/mocking 的新手,尤其是 python 的新手。我正在尝试修补将在测试用例中使用以下内容访问的字典

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_dict'

类 如下:

class Foo(object):
    def __init__(self, barVal):
        self.bar = barVal

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

不确定您的情况是否需要 patchPatch 更常用于模块的 'mocking' 功能。您可以使用 Mock 对象创建用于测试的结构(使用 'mocked' 方法和属性)。

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

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

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' 方法和属性),而不需要原始 class 的 'patching'。示例:

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]

在某些情况下,我们需要 'mock' class 的方法(例如用于小组测试)。在这种情况下,您可以使用 patch:

    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()

希望这对您有所帮助。