【问题标题】:How to patch Python class using Mock library如何使用 Mock 库修补 Python 类
【发布时间】:2012-06-24 16:39:39
【问题描述】:

我无法为我的测试修补课程。我正在尝试修补属于 Scrapy 的东西 - HtmlXpathSelector 类。

这里有一些代码:

from scrapy.selector import HtmlXPathSelector
from mock import MagicMock, patch

with patch('scrapy.selector.HtmlXPathSelector') as MockHtml:
    instance = MockHtml.return_value
    instance.method.return_value = 'foo'
    example = HtmlXPathSelector()
    print type(example)
    assert example is instance
    assert example.method == 'foo'

结果是:

<class 'scrapy.selector.lxmlsel.HtmlXPathSelector'>
Traceback (most recent call last):
  File "<stdin>", line 6, in <module>
AssertionError
>>>

此示例与 Mock 库教程中的示例几乎相同。知道为什么它不起作用吗?

【问题讨论】:

    标签: python unit-testing mocking scrapy python-mock


    【解决方案1】:

    您不应修补已在当前测试代码中导入的类。相反,您需要修补相应模块中的类(您要测试)。所以如果HtmlXPathSelector被导入到mymodule中,你会打补丁为:

    with patch('mymodule.HtmlXPathSelector') as MockClass:
        ...
    

    更多详情请参阅where to patch

    编辑如果你真的需要这个,你可以在当前模块中修补一个类:

    with patch('__main__.Class') as MockClass:
    

    【讨论】:

    • 啊!这就是我想要的......我现在明白了,这种方法回答了我在 Ned 的回答中的评论。谢谢!
    • Link where-to-patch at the momemnt 返回 503。
    • @Drachenfels 谢谢,将链接更改为指向 readthedocs,应该更稳定。
    【解决方案2】:

    您的代码示例存在两个问题。第一个是您已经从 scrapy 模块导入了 HtmlXPathSelector,然后您在事后更改了该名称。而是导入选择器,并使用那里的名称:

    from scrapy import selector
    from mock import MagicMock, patch
    
    with patch('scrapy.selector.HtmlXPathSelector') as MockHtml:
        instance = MockHtml.return_value
        instance.method.return_value = 'foo'
        example = selector.HtmlXPathSelector()
        print type(example)
        assert example is instance
        assert example.method() == 'foo'
    

    另一个问题是你的最后一行是检查method,当它需要调用method()的方法时。

    【讨论】:

    • 这太好了,谢谢!唯一的问题是,我在我的问题中给出的示例稍微简化了......实际情况是,在我正在测试的模块中,mypackage.foo_moduleHtmlXPathSelector 是这样导入的:from scrapy.selector import HtmlXPathSelector,然后是函数我正在测试有一个实例化,例如hxs = HtmlXPathSelector(XX)。我是否必须更改我正在测试的类中的代码才能让它全部工作?
    • 要么更改您的产品代码以导入此示例的方式,要么使用patch('mypackage.foo_module.HtmlXPathSelector')。第二种方式可能更好,因为它是更本地化的更改。
    • 我现在明白了,内德,谢谢。很偶然,我只是在这里blip.tv/pycon-us-videos-2009-2010-2011/… 听你的演讲。然后你回答了我的测试问题。多么奇怪。 :-)
    猜你喜欢
    • 2014-09-02
    • 2012-04-24
    • 2012-09-01
    • 1970-01-01
    • 2011-07-17
    • 2012-05-03
    • 1970-01-01
    • 2019-09-12
    • 1970-01-01
    相关资源
    最近更新 更多