Mocking eine Django-Queryset, um zu testen, eine Funktion, ein queryset
Habe ich eine utility-Funktion in meinem Django-Projekt, es dauert ein queryset, ruft einige Daten aus und gibt ein Ergebnis zurück. Ich würde gerne schreiben, einige tests für diese Funktion. Es ist trotzdem 'mock' ein QuerySet? Ich möchte ein Objekt erstellen, dass nicht auf die Datenbank zugegriffen wird, und ich kann es mit einer Liste der Werte zu verwenden (d.h. einige fake-Zeilen) und dann werde es handeln wie ein queryset, und wird erlauben, jemanden zu Feld-lookups auf es/filter/get/alle usw..
Macht so etwas gibt es bereits?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nicht, dass ich wüsste, aber warum nicht verwenden eine tatsächliche queryset? Das test-framework ist, alle eingerichtet, um zu ermöglichen das erstellen von sample-Daten in Ihre Prüfung, und die Datenbank wird neu erstellt, auf jeden test, so scheint es nicht zu sein aus irgendeinem Grund nicht zu nutzen, die Reale Sache.
Natürlich können Sie mock ein QuerySet, können Sie mock nichts.
Können Sie erstellen, die ein Objekt selbst, und geben Sie die Schnittstelle, die Sie brauchen, und haben es wieder alle Daten, die Sie mögen. Bei Herz -, Spott ist nichts mehr als ein "Doppel-test", das wirkt genug, wie die Reale Sache für Ihre tests Zwecke.
Den low-tech-Weg, um loszulegen ist ein Objekt definieren:
erstellen Sie dann eine von diesen, und geben Sie es zu Ihrem test. Der test schlägt fehl, wahrscheinlich auf eine
AttributeError
. Das wird Ihnen sagen, was Sie implementieren müssen, um auf IhreMockQuerySet
. Wiederholen Sie, bis Ihr Objekt ist Reich genug, um Ihre tests.Ich habe das gleiche Problem, und es sieht aus wie ein netter Mensch geschrieben hat, eine Bibliothek für Spott QuerySets, heißt es mock-django und den spezifischen code, den Sie benötigen, ist hier https://github.com/dcramer/mock-django/blob/master/mock_django/query.py ich denke, man kann dann nur patchen Sie Modelle von Objekten-Funktion zum zurückgeben einer dieser QuerySetMock Objekte, die Sie eingerichtet haben, um etwas zurück zu erwarten!
Für eine leere Queryset, dann würde ich einfach für die Verwendung
none
als keithhackbarth bereits erklärt hat.Jedoch zu verspotten, ein Queryset, das gibt eine Liste der Werte, die ich lieber verwenden eine Mock mit einem
spec
des Modells-manager. Als ein Beispiel (Python 2.7-Stil - Ich habe die externe Mock-Bibliothek), hier ist ein einfacher test, bei dem die Queryset gefiltert und dann gezählt:Jedoch zu erfüllen, die Frage, statt der Einstellung eine
return_value
fürcount
, dies könnte leicht angepasst werden, um einelist
von Modell-Instanzen zurückgegeben, die vonall
.Beachten Sie, dass die Verkettung erfolgt durch Einstellung der
filter
zurückgeben verspottet queryset:Dieser muss angewendet werden für alle queryset Methoden verwendet, die in der Funktion unter-test, z.B.
exclude
usw.Dazu benutze ich Django ist .none () - Funktion.
Beispiel:
Diese Methode wird Häufig in Django-eigenen, internen test-Fällen. Basierend auf Kommentare in den code
.none
! Vielen Dank - das ist super hilfreich.Haben Sie schaute in FactoryBoy? https://factoryboy.readthedocs.io/en/latest/orms.html
Es ist ein Leuchten-ersetzen-Werkzeug mit Unterstützung für das django-orm - Fabriken grundsätzlich generieren orm-ähnlichen Objekte (entweder im Speicher oder in einer test-Datenbank).
Hier ist ein toller Artikel für den Einstieg: https://www.caktusgroup.com/blog/2013/07/17/factory-boy-alternative-django-testing-fixtures/
Versuchen, die
django_mock_queries
- Bibliothek können Sie mock aus den Zugriff auf die Datenbank, und noch einige Django-Abfrage-set-Funktionen, wie Filterung.Vollständige Offenlegung: ich trug einige features für das Projekt.
Können Sie mock so:
Einer ersten Beratung wäre zum aufteilen der Funktion in zwei Teile, eine, die schafft das queryset
und einer, der manipuliert die Ausgabe von es. Auf diese Weise testen, der zweite Teil ist einfach.
Für die Datenbank das problem, das ich untersucht, ob django verwendet sqlite-in-memory-und ich fand heraus, dass
neueste version von django verwendet den sqlite -in-memory-Datenbank, aus Die django-unittest-Seite:
Lustig das QuerySet-Objekt wird nicht machen Sie die Ausübung seiner vollen Logik.