2016-09-30 1 views
1

Was würde ich tun möchte, ist dies ...Kann ein MagicMock-Objekt durchlaufen werden?

x = MagicMock() 
x.iter_values = [1, 2, 3] 

for i in x: 
    i.method() 

Ich versuche, eine Unit-Test für diese Funktion zu schreiben, aber ich bin nicht sicher, wie man ohne Aufruf einige externe gehen etwa genannt alle Methoden spöttischen Ressource ...

def wiktionary_lookup(self): 
    """Looks up the word in wiktionary with urllib2, only to be used for inputting data""" 
    wiktionary_page = urllib2.urlopen(
     "http://%s.wiktionary.org/wiki/%s" % (self.language.wiktionary_prefix, self.name)) 
    wiktionary_page = fromstring(wiktionary_page.read()) 
    definitions = wiktionary_page.xpath("//h3/following-sibling::ol/li") 
    print definitions.text_content() 
    defs_list = [] 
    for i in definitions: 
     print i 
     i = i.text_content() 
     i = i.split('\n') 
     for j in i: 
      # Takes out an annoying "[quotations]" in the end of the string, sometimes. 
      j = re.sub(ur'\u2003\[quotations \u25bc\]', '', j) 
      if len(j) > 0: 
       defs_list.append(j) 
    return defs_list 

EDIT:

I Mocks werden mißbrauchen kann, ich bin nicht sicher. Ich versuche Unit wiktionary_lookup Methode ohne Aufruf externer Dienste zu testen ... so ich mock urlopen..I mock fromstring.xpath() aber soweit ich sehen kann, muss ich auch durchlaufen den Rückgabewert von xpath() und rufen Sie an eine Methode "text_contents()" also das ist, was ich hier versuche.

Wenn ich völlig falsch verstanden haben, wie diese Methode zu Unittest dann mir bitte sagen, wo ich schief gelaufen ...

EDIT (Hinzufügen von aktuellen Unittest-Code)

@patch("lang_api.models.urllib2.urlopen") 
@patch("lang_api.models.fromstring") 
def test_wiktionary_lookup_2(self, fromstring, urlopen): 
    """Looking up a real word in wiktionary, should return a list""" 
    fromstring().xpath.return_value = MagicMock(
     content=["test", "test"], return_value='test\ntest2') 
    # A real word should give an output of definitions 
    output = self.things.model['word'].wiktionary_lookup() 
    self.assertEqual(len(output), 2) 
+0

Was möchten Sie in Ihrem Komponententest genau vortäuschen? Auch Ihr 'MagicMock' Beispiel. Was versuchst du genau mit dieser Liste zu machen? Ich vermute, Sie missbrauchen die Mocks hier. Aber ich bin mir nicht sicher, was genau Sie vorhaben. – idjaw

+0

@idjaw, eine Antwort als EDIT hinzugefügt – deltaskelta

+0

Können Sie Ihren Unittest-Code zeigen, um zu sehen, wo Vorschläge zur Verbesserung bereitgestellt werden könnten? – idjaw

Antwort

1

Was Sie wirklich tun wollen ist nicht eine Mock mit einer return_value=[] zurückgeben. Sie möchten tatsächlich einen list von Mock Objekte zurückgeben. Hier ist ein Ausschnitt des Testcode mit den richtigen Komponenten und ein kleinen Beispiel zu zeigen, wie in der Schleife eine der Iterationen testen:

@patch('d.fromstring') 
@patch('d.urlopen') 
def test_wiktionary(self, urlopen_mock, fromstring_mock): 
    urlopen_mock.return_value = Mock() 
    urlopen_mock.return_value.read.return_value = "some_string_of_stuff" 

    mocked_xpath_results = [Mock()] 
    fromstring_mock.return_value.xpath.return_value = mocked_xpath_results 

    mocked_xpath_results[0].text_content.return_value = "some string" 

Also, den obigen Code zu sezieren, zu erklären, was getan wurde zu korrigieren Ihr Problem:

das erste, was uns mit dem testen Sie den Code in der for-Schleife zu helfen, ist eine Liste von Mock-Objekte pro zu erstellen:

mocked_xpath_results = [Mock()] 

Dann wird, wie Sie von

01 sehen

Wir setzen den return_value des xpath Anrufs auf unsere Liste der Mocks per mocked_xpath_results.

Als Beispiel dafür, wie die Dinge in Ihrer Liste zu tun, habe ich wie in der Schleife zu verspotten, die mit angezeigt:

mocked_xpath_results[0].text_content.return_value = "some string" 

In Unittests (dies könnte eine Frage der Meinung sein) Ich mag Um explizit zu sein, greife ich explizit auf das Listenelement zu und erkläre, was passieren soll.

Hoffe, das hilft.

+1

Danke für die Antwort. Ich habe die Antwort aus dem echten Wiktionary als Variable gespeichert und sie dann importiert und einen semi-real 'fromstring' ausgeführt, den ich dann umgestalten werde, wenn ich Zeit habe. Vielen Dank – deltaskelta

Verwandte Themen