2017-02-13 3 views
1

Bearbeiten: Dies ist möglicherweise das gleiche Problem wie in diesem Python-Fehler beschrieben: https://bugs.python.org/issue26752. Aber dieser Bug hat seit einem Jahr gesessen, deshalb bin ich immer noch an den Meinungen der Leute interessiert.Was ist mit diesem einfachen "unittest.mock" Anwendungsfall falsch?


Ich bin mir nicht sicher, ob dies ein Fehler in unittest.mock ist oder ich falsch verstehen nur etwas.

Hier ist der Code - Sie können es als test.py

from unittest.mock import patch, call 

class Foo: 
    def __init__(self): 
     pass 
    def my_method(self, value): 
     pass 

def test_foo(): 
    with patch('test.Foo', autospec=True) as MockFoo: 
     m = Foo() 
     m.my_method(123) 
     MockFoo.assert_has_calls([call(), call().my_method(123)]) 

speichern kann ich diesen Test laufen wie folgt:

$ py.test test.py 

Und ich bekomme diesen Fehler:

... 
E    AssertionError: Calls not found. 
E    Expected: [call(), call().my_method(123)] 
E    Actual: [call(), call().my_method(123)] 

Die Frage: Ist das richtiges Verhalten? Es scheint mir fehlerhaft. Die Liste der Anrufe entspricht genau, also was gibt?

Interessanterweise, wenn ich den value Parameter von my_method und auch die 123 Eingänge im Test entfernen, dann geht alles!

Was fehlt mir hier?

Info Version:

$ py.test --version 
This is pytest version 3.0.6, imported from /usr/local/lib/python3.4/site-packages/pytest.py 
$python3.4 --version 
Python 3.4.5 

auch versucht, dies auf 3,5 in einem virtualenv:

$ py.test --version 
This is pytest version 3.0.6, imported from /usr/home/jwd/virtualenv/pytest-3.5/lib/python3.5/site-packages/pytest.py 
$ python3.5 --version 
Python 3.5.2 
+1

Das macht überhaupt keinen Sinn. Es gibt so viele Fragen, ich weiß nicht einmal, wo ich anfangen soll ... warum verspottest du 'Foo', wenn du es testen willst? – hop

+0

@hop: Dies ist ein minimalistisches Beispiel für ein Problem, das ich in einer größeren Anzahl von Tests festgestellt habe. Bitte erwarte nicht, dass dieser Code alleine sinnvoll ist (: Das Problem, das ich versuche zu verstehen, ist, warum 'assert_has_calls' dieses (meiner Meinung nach) nicht-intuitive Verhalten hat, wenn Argumente übergeben werden. – jwd

+0

@hop: aber wenn Du musst wissen, dass ich im echten Code eine Methode teste, die * 'Foo' verwendet. Diese Methode ist diejenige, die' Foo' instanziiert und 'my_method (123)' aufruft. Ich habe es gerade in den Test hier hinein gesteckt Abkürzung – jwd

Antwort

1

EDIT: gelöscht fehlerhafte vorherige Antwort.

Bitte können Sie versuchen:

expected_calls = [call(), call().my_method(123)] 
assert MockFoo.mock_calls == expected_calls 

Dies funktioniert für mich auf Python 3.5.2.

Dies wird direkt aus der Dokumentation entnommen: https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock.mock_calls

+0

Ich habe es gerade so versucht, mit dem gleichen Fehler. Aber dann habe ich es auch bei 3.5.2 probiert und auch den gleichen Fehler bekommen. Sind Sie 100% sicher, dass Sie es genau kopiert haben? Sehr merkwürdig, wenn sich dein 3.5.2 von meinem unterscheidet ... – jwd

+0

Ah, ich denke du hast auch auf der Mailingliste geantwortet - ich habe da eine ausführlichere Antwort gegeben. Für SO Leute: http://lists.idyll.org/pipermail/testing-in-python/2017-February/007009.html – jwd

+0

Ja, die explizite '==' Prüfung auf der Anrufliste funktioniert auch für mich. Das ist interessant. Ich würde erwarten, dass 'X.mock_calls == Y' das gleiche Verhalten wie' X.assert_has_calls (Y) 'hat (zumindest in dem Fall, in dem die Listen identisch sind - ich weiß, dass' assert_has_calls' einige feinere partielle Übereinstimmungen enthält) komplexere Fälle). – jwd