2013-10-05 10 views
6

Ich versuche, die Urllib2.urlopen-Bibliothek in einer Weise zu verspotten, dass ich unterschiedliche Antworten für verschiedene URLs erhalten sollte, die ich in die Funktion übergebe.Mocking urllib2.urlopen(). Read() für verschiedene Antworten

So wie ich es jetzt in meiner Testdatei tue, ist wie dies

@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 

erwarte ich, dass das die othermodule.function_to_be_tested den Wert „Reaktionszeit1“ auf dem ersten Anruf und „response2“ auf dem zweiten Anruf zu erhalten, die ist das, was side_effect

aber die othermodule.function_to_be_tested tun() erhält

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

und nicht die tatsächliche Antwort. Bitte geben Sie an, wo ich falsch liege oder einen einfacheren Weg.

+1

Sie können einfach '@patch (urllib2.urlopen)' direkt patchen. –

+0

Ich versuche, die Kopie zu patchen, die in meinem anderen Modul importiert wird. Ich denke, das ist die Art und Weise, wie es gemacht werden sollte – quirkystack

+0

Ich würde persönlich nur meinen Code umgestalten, um nicht hardcodiert zu sein, urlib.urlopen überhaupt zu verwenden; z.B. es würde "self.urlopen_fn" aufrufen, dessen Standardwert "urllib.urlopen" ist, aber das Sie während des Testens einfach auf 'your_mock_urlopen' setzen können; Es kann sogar ein Parameter auf Modulebene sein, den Sie von außen einstellen können. –

Antwort

12

Das Argument patch muss eine Beschreibung der Lage des Objekts sein, nicht das Objekt selbst . Ihr Problem sieht also so aus, als ob Sie Ihr Argument einfach an patch anhängen müssen.

Nur der Vollständigkeit halber, hier ist ein voll funktionsfähiges Beispiel. Zuerst unser Modul im Test:

# mod_a.py 
import urllib2 

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

nun unser Test ein:

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

den Test aus der Schale Rennen:

$ python test.py 
resp1 
resp2 

bearbeiten: Whoops, zunächst enthalten der ursprüngliche Fehler. (Wurde getestet, um festzustellen, wie es defekt war.) Der Code sollte jetzt behoben sein.

Verwandte Themen