代码之家  ›  专栏  ›  技术社区  ›  tsar2512

python中的模拟字典

  •  1
  • tsar2512  · 技术社区  · 7 年前

    我对修补/模拟一般来说是新手,尤其是python。我正在尝试修补一个dict,该dict将在测试用例中使用以下命令访问

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

    但我得到以下错误。请理解 __init__() Foo makes酒吧的功能 None 默认情况下

    AttributeError:“NoneType”对象没有属性“items\u dict”

    分类如下:

    class Foo(object):
        def __init__(self, barVal):
            self.bar = barVal
    
    class Bar():
        def __init__(self, val)
            self.items_dict = {}
            self._load(val)
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   Danila Ganchar    7 年前

    不确定您是否需要 patch 在你的情况下。 Patch 更多的人使用“模拟”模块的功能。您可以使用 Mock 对象创建用于测试的结构(使用“模拟”方法和属性)。

    首先,我认为你出错是因为你发送了 None 到 构造函数。但是 NoneType 没有 items_dict 所有物

    下面是一个可以帮助您的小示例:

    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'}
            )
    

    让我们总结一下。 你出错是因为你试图 items\u目录 属于 没有一个 类型(看起来像: a = None a.items_dict )。 您可以创建任何用于测试的对象(使用“模拟”方法和属性),而无需对原始类进行“修补”。示例:

    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]
    

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

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

    希望这有帮助。