Mocking default = timezone.now für Komponententests

9

Ich versuche Einheitentests für eine Django-App zu schreiben, die viele Datetime-Operationen ausführt. Ich habe mock installiert, um die timezone.now von affe patch django für meine Tests zu installieren.

Obwohl ich timezone.now erfolgreich verkünden kann, wenn es normal aufgerufen wird (tatsächlich ruft timezone.now() in meinem Code auf, kann ich es nicht für Modelle vortäuschen, die mit DateTimeField mit default=timezone.now erstellt wurden.

Ich habe ein User -Modell, das Folgendes enthält:

%Vor%

Mein Komponententest sieht so aus:

%Vor%

assertEquals(user.modified, dt) wird übergeben, aber assertEquals(user.timestamp, dt) nicht.

Wie kann ich timezone.now vortäuschen, so dass auch default=timezone.now in meinen Modellen die Mockzeit erstellt?

Bearbeiten

Ich weiß, dass ich einfach meinen Einheitentest ändern könnte, um ein timestamp meiner Wahl zu übergeben (wahrscheinlich erzeugt durch das verspottete timezone.now ) ... Neugierig, wenn es einen Weg gibt, der das jedoch vermeidet.

    
dgel 20.09.2013, 19:58
quelle

4 Antworten

10

Ich bin gerade selbst auf dieses Problem gestoßen. Das Problem besteht darin, dass die Modelle geladen werden, bevor der Zeitzonenmodul von mock gepatcht wurde. Zu dem Zeitpunkt, zu dem der Ausdruck default=timezone.now ausgewertet wird, setzt er default kwarg auf die echte Funktion timezone.now .

Die Lösung ist die folgende:

%Vor%     
Jordan Carlson 03.10.2013, 21:44
quelle
5

Hier ist eine Methode, die Sie verwenden können, ohne dass Sie Ihren Nicht-Test-Code ändern müssen. Patchen Sie einfach die default Attribute der Felder, die Sie beeinflussen möchten. Zum Beispiel -

%Vor%

Sie können Hilfsfunktionen schreiben, um dies weniger ausführlich zu machen. Zum Beispiel der folgende Code -

%Vor%

würde Sie schreiben lassen -

%Vor%

Sie können auch Helferkontextmanager schreiben, um mehrere Felder gleichzeitig zu patchen.

    
cjerdonek 10.02.2014 12:22
quelle
0

Sieht so aus, als ob Sie die Zeitzone im patchen falscher Ort.

Angenommen, Ihr User -Modell lebt in myapp\models.py und Sie möchten save() in dieser Datei testen. Das Problem ist, dass wenn Sie from django.utils import timezone an der Spitze, importiert es es von django.utils . In Ihrem Test patchen Sie timezone lokal, und das hat keine Auswirkungen auf Ihren Test, da das Modul myapp\models.py bereits einen Verweis auf das echte timezone hat und es so aussah, als hätte unser Patch keinen Effekt.

Versuchen Sie timezone von myapp\models.py zu patchen, etwas wie:

%Vor%     
Oleksiy 20.09.2013 20:19
quelle
0

Es gibt einen anderen einfachen Weg, um das oben genannte zu tun.

%Vor%

Dies ist der beste Weg, um timezone.now zu verspotten.

    
Tahir Fazal 30.08.2017 10:11
quelle