2012-06-22 61 views
3

我在爲測試修補類時遇到問題。我正在嘗試修補屬於Scrapy的東西 - HtmlXpathSelector課程。如何使用模擬庫修補Python類

下面是一些代碼:

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

這個例子是一樣的一個在素庫教程近了。任何想法爲什麼它不工作?

回答

6

您不應該修補已在當前測試代碼中導入的類。相反,您需要在相應的模塊中修補該類(您要測試)。所以,如果HtmlXPathSelectormymodule進口的,你會打補丁:

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

進一步詳情,請參閱where to patch

編輯如果你真的需要這一點,你可以在當前模塊中修補類:

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

啊!這就是我想要的......我現在明白了,這種方法回答了我在內德答案中的評論。謝謝! – Edwardr

+0

鏈接到momemnt的補丁返回503. – Drachenfels

+0

@Drachenfels謝謝,將鏈接改爲指向readthedocs,應該更穩定。 – schlamar

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

+0

這太棒了,謝謝!唯一的問題是,我在我的問題中給出的例子稍微簡化了......現實情況是,在我測試的模塊中,'mypackage.foo_module','HtmlXPathSelector'是這樣導入的:'from scrapy.selector import HtmlXPathSelector',然後我正在測試的函數有一個實例,如'hxs = HtmlXPathSelector(XX)'。我是否必須更改我正在測試的課程中的代碼才能使所有這些工作都可行? – Edwardr

+0

請更改您的產品代碼以導入本示例的方式,或使用'patch('mypackage.foo_module.HtmlXPathSelector')'。第二種方式可能更好,因爲它是一種更本地化的更改。 –

+0

我明白了,奈德,謝謝。相反,我在這裏只是聽你的談話http://blip.tv/pycon-us-videos-2009-2010-2011/pycon-2010-tests-and-testability-188-3280697。然後你回答了我的測試問題。多麼奇怪。 :-) – Edwardr