Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking urllib2.urlopen().read() for different responses

I am trying to mock the urllib2.urlopen library in a way that I should get different responses for different urls I pass into the function.

The way I am doing it in my test file now is like this

@patch(othermodule.urllib2.urlopen)
def mytest(self, mock_of_urllib2_urllopen):
    a = Mock()
    a.read.side_effect = ["response1", "response2"]
    mock_of_urllib2_urlopen.return_value = a
    othermodule.function_to_be_tested()   #this is the function which uses urllib2.urlopen.read

I expect the the othermodule.function_to_be_tested to get the value "response1" on first call and "response2" on second call which is what side_effect will do

but the othermodule.function_to_be_tested() receives

<MagicMock name='urlopen().read()' id='216621051472'>

and not the actual response. Please suggest where I am going wrong or an easier way to do this.

like image 222
quirkystack Avatar asked Oct 05 '13 23:10

quirkystack


1 Answers

The argument to patch needs to be a description of the location of the object, not the object itself. So your problem looks like it may just be that you need to stringify your argument to patch.

Just for completeness, though, here's a fully working example. First, our module under test:

# mod_a.py
import urllib2

def myfunc():
    opened_url = urllib2.urlopen()
    return opened_url.read()

Now, set up our test:

# test.py
from mock import patch, Mock
import mod_a

@patch('mod_a.urllib2.urlopen')
def mytest(mock_urlopen):
    a = Mock()
    a.read.side_effect = ['resp1', 'resp2']
    mock_urlopen.return_value = a
    res = mod_a.myfunc()
    print res
    assert res == 'resp1'

    res = mod_a.myfunc()
    print res
    assert res == 'resp2'

mytest()

Running the test from the shell:

$ python test.py
resp1
resp2

Edit: Whoops, initially included the original mistake. (Was testing to verify how it was broken.) Code should be fixed now.

like image 63
spiffyman Avatar answered Oct 20 '22 04:10

spiffyman