简体   繁体   English

如何使用 Mock 库修补 Python 类

[英]How to patch Python class using Mock library

I'm having trouble patching a class for my testing.我在为我的测试修补类时遇到问题。 I'm trying to patch something that belongs to Scrapy - a HtmlXpathSelector class.我正在尝试修补属于 Scrapy 的东西——一个HtmlXpathSelector类。

Here is some code:这是一些代码:

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'

The result is:结果是:

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

This example is nigh on the same as the one in the Mock library tutorial.这个示例与 Mock 库教程中的示例几乎相同。 Any idea why it's not working?知道为什么它不起作用吗?

You should not patch a class already imported in the current test code.您不应修补已在当前测试代码中导入的类。 Instead you need to patch the class in the corresponding module (you want to test).相反,您需要修补相应模块中的类(您要测试)。 So if HtmlXPathSelector is imported in mymodule , you will patch as:因此,如果在mymodule导入HtmlXPathSelector ,您将修补为:

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

See where to patch for further details.有关更多详细信息,请参阅修补位置

Edit If you really need this, you can patch a class in the current module with:编辑如果你真的需要这个,你可以在当前模块中修补一个类:

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

There are two problems with your code sample.您的代码示例有两个问题。 The first is that you've imported HtmlXPathSelector from the scrapy module, then you change that name after the fact.第一个是您已经从 scrapy 模块导入了 HtmlXPathSelector,然后在事后更改了该名称。 Import selector instead, and use the name from there:改为导入选择器,并使用那里的名称:

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'

The other problem is that your last line was checking method , when it needs to invoke the method as method() .另一个问题是你的最后一行是检查method ,当它需要调用方法作为method()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM