Mit mock zu patch Sellerie Aufgabe in Django unit-tests
Ich versuche, verwenden Sie die python-mock-Bibliothek zu patchen Sellerie Aufgabe, die ausgeführt wird, wenn ein Modell gespeichert wird, in meinem django-app, um zu sehen, dass es aufgerufen wird, richtig.
Grundsätzlich die Aufgabe definiert ist, innerhalb myapp.tasks
, und importiert wird, an der Spitze meiner Modelle.py-Datei so auf:
from .tasks import mytask
...und dann läuft auf save()
im Modell mit mytask.delay(foo, bar)
. So weit, so gut - funktioniert auch ganz gut, wenn ich bin tatsächlich läuft Celeryd etc.
Ich bauen will ein unit-test, mocks die Aufgabe, genau zu überprüfen, dass es aufgerufen wird, mit den richtigen Argumenten, und nicht tatsächlich versuchen, führen Sie den Sellerie Aufgabe überhaupt.
So, in der test-Datei, ich habe etwas in einem normalen TestCase:
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 die überprüfung, ob mock_task.delay
genannt wurde, statt. Ich gesammelt habe aus den mock-docs, die die import-Pfad ist entscheidend, und googeln sagt mir, dass es sein sollte, der Weg wie es gesehen wird, in dem Modul unter tests (das wäre myapp.models.mytask.delay
eher als myapp.tasks.mytask.delay
, wenn ich es richtig verstanden habe).
Wo bin ich denn hier falsch? Gibt es einige spezifische Schwierigkeiten patchen Sellerie Aufgaben? Könnte ich patch celery.task
(dient als decorator um mytask
) statt?
- haben Sie versucht, die Einstellung "CELERY_ALWAYS_EAGER = True" anstelle von mock es?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das Problem, dass Sie unabhängig von der Tatsache, dass dies ein Sellerie Aufgabe. Sie passieren einfach zu patchen die falsche Sache. 😉
Insbesondere müssen Sie herausfinden, welche anzeigen oder andere Datei importieren "mytask" und patch es dort zu, so dass die entsprechende Zeile würde wie folgt Aussehen:
Gibt es etwas mehr Geschmack zu diesem hier:
http://www.voidspace.org.uk/python/mock/patch.html#where-to-patch
mytask.delay()
innerhalb der überschriebenensave()
Methode auf das Modell, wirklich. (Ich bin mit der Aufgabe zum senden von Daten aus dem Modell an ein externes system). Würde das für einen Unterschied, wie das patchen funktioniert?CELERY_ALWAYS_EAGER
,BROKER_BACKEND
, etc) haben nicht funktioniert.Den
@task
Dekorator ersetzt die Funktion mit einemTask
- Objekt (siehe Dokumentation). Wenn Sie verhöhnen die Aufgabe selbst werde Sie ersetzen die (etwas Magie)Task
Objekt mit einemMagicMock
und es wird nicht die Aufgabe an alle. Stattdessen verspotten derTask
Objektrun()
- Methode, etwa so:delay()
Methode, während wahrscheinlich die Arbeit in einem konkreten Fall tatsächlich die falsche Antwort, weil Sie vielleicht später ändern Sie den code verwendenapply_async()
oder eine andere Methode, und plötzlich, dass Ihre tests eine Pause für den falschen Grund.CELERY_TASK_ALWAYS_EAGER