Search code examples
pythonunit-testingmockingscrapypython-mock

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.

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. Any idea why it's not working?


Solution

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

    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: