2013-08-13 5 views
18

Ich versuche, die Python-Mock-Bibliothek zu Patch eine Sellerie Aufgabe, die ausgeführt wird, wenn ein Modell in meiner Django-App, um zu sehen, dass es richtig aufgerufen wird.Verwenden von Mock, um eine Sellerie Aufgabe in Django Komponententests zu patch

Grundsätzlich ist die Aufgabe innerhalb myapp.tasks definiert und wird wie so an der Spitze meiner models.py-Datei importiert:

from .tasks import mytask

... und läuft dann auf save() im Inneren des Modells . So weit so gut - funktioniert gut, wenn ich tatsächlich Celeryd usw. betreibe.

Ich möchte einen Komponententest konstruieren, der die Aufgabe verspottet, nur um zu überprüfen, dass sie mit den richtigen Argumenten aufgerufen wird und nicht wirklich Versuchen Sie, die Sellerie-Aufgabe jemals auszuführen.

So in der Testdatei, ich so etwas wie dies innerhalb einer Standard-Testcase habe:

from mock import patch # at the top of the file 

# ...then later 
def test_celery_task(self): 
    with patch('myapp.models.mytask.delay') as mock_task: 
     # ...create an instance of the model and save it etc 
     self.assertTrue(mock_task.called) 

... aber es wird nie genannt/ist immer falsch. Ich habe versucht, verschiedene Inkarnationen (patchen myapp.models.mytask statt, und überprüfen, ob mock_task.delay wurde stattdessen aufgerufen. Ich habe aus der Mock Docs, dass der Import-Pfad ist entscheidend, und Googling sagt mir, dass es sollte der Weg sein, wie es in der gesehen wird Modul unter Tests (die myapp.models.mytask.delay statt myapp.tasks.mytask.delay wäre, wenn ich es richtig verstehe).

Wohin gehe ich hier falsch? gibt es einige spezifische Schwierigkeiten in Sellerie Aufgaben patchen? Könnte ich celery.task (die als ein verwendet wird Patch Dekorateur zu mytask) statt?

+1

haben Sie versucht, „CELERY_ALWAYS_EAGER = True“ statt verspotten es einstellen? – clsung

Antwort

21

Das Problem, das Sie haben, ist unabhängig von der Tatsache, dass dies eine Sellerie Aufgabe ist.Sie ​​nur zufällig die falsche Sache zu patchen.; Insbesondere)

, müssen Sie welche Ansicht oder eine andere Datei, um herauszufinden, ist die Einfuhr von „MyTask“ und es dort Patch, so dass die entsprechende Zeile würde wie folgt aussehen:

with patch('myapp.myview.mytask.delay') as mock_task: 

Es gibt etwas mehr Geschmack dies hier:

http://www.voidspace.org.uk/python/mock/patch.html#where-to-patch

+0

Prost! Ich muss es noch ausprobieren (Projekt ruht gerade), werde es aber bald ausprobieren und dies als beantwortet markieren. Ich erinnere mich, dass ich einige Variationen des Themas ausprobiert habe, die Sie vorschlagen, aber es ist durchaus möglich, dass mein Blutzucker zu der Zeit niedrig war ... :-) – Emil

+1

Eigentlich mache ich das ziemlich genau so, wie Sie es vorschlagen , wie im Fragecode beispielhaft dargestellt ... Kann es nicht zur Arbeit bringen. Naja. – Emil

+0

Die Frage ist das Patchen des Modells. Das riecht falsch, da ich vermute, dass Sie keine "Verzögerung" im Modell verwenden, sondern woanders - möglicherweise eine Ansicht, daher ist mein Patch-Code (oben) etwas anders. –

18

Der @task Dekorateur ersetzt die Funktion mit einem Task Objekt (siehe documentation). Wenn Sie die Aufgabe selbst verspotten, ersetzen Sie das (etwas magische) Task Objekt durch eine MagicMock und es wird die Aufgabe überhaupt nicht geplant. Stattdessen verspotten die run() Methode des Task Objekt, etwa so:

@override_settings(CELERY_ALWAYS_EAGER=True) 
@patch('monitor.tasks.monitor_user.run') 
def test_monitor_all(self, monitor_user): 
    """ 
    Test monitor.all task 
    """ 

    user = ApiUserFactory() 
    tasks.monitor_all.delay() 
    monitor_user.assert_called_once_with(user.key) 
+1

Gibt es einen Grund, warum Sie diese Antwort Wort für Wort auf zwei Fragen geschrieben haben? –

+0

Es ist ziemlich nützliche Informationen zu dieser Frage sowie die andere. Sie sind jedoch nicht genau die gleiche Frage. –

+0

BTW Wenn Sie denken, dass eine Antwort für zwei Fragen verwandt und nützlich ist, können Sie eine davon als Duplikat kennzeichnen und jemand wird sich darum kümmern. Post die gleiche Antwort ist die falsche Sache zu tun. –

Verwandte Themen