2016-05-17 3 views
2

würde Ich mag Timing verspotten, so dass in der Lage sein zu gesetzt bestimmten Zeit auf ein Feld vom Typ DateTimeField mit auto_now_add=True während meiner Tests zB:Mock Timing in einem Kontextmodell mit einem Feld Datetimefield mit auto_now_add erstellen = True

class MyModel: 
    ... 
    created_at = models.DateTimeField(auto_now_add=True) 
    ... 


class TestMyModel(TestCase): 
    ... 
    def test_something(self): 
     # mock current time so that `created_at` be something like 1800-02-09T020000 
     my_obj = MyModel.objects.create(<whatever>) 
     # and here my_obj.created_at == 1800-02-09T000000 

ich bin mir bewusst, das aktuelle Datum always für diese Art von Feldern verwendet wird, deshalb suche ich eine Alternative irgendwie das System-Timing zu verspotten, aber nur in einem Kontext.

Ich habe einige Ansätze ausprobiert, zum Beispiel, einen Zusammenhang mit freeze_time zu schaffen, sondern hat nicht funktioniert:

with freeze_now("1800-02-09"): 
    MyModel.objects.create(<whatever>) 
    # here the created_at doesn't fit 1800-02-09 

Ofc denke ich, ist dies aufgrund der Maschinerie hinter, wie es das Objekt erstellt wird mit auto_now_add=True.

Ich möchte nicht auto_now_add=True entfernen und Standardwerte verwenden.

Gibt es eine Möglichkeit, wir können das Timing verspotten, so dass wir tun können, dass diese Art von Feld bekommen die Zeit, die ich in bestimmten Kontext will?

Ich Django 1.9.6 und Python 3.4

+0

Django- und Python-Versionen? – theWanderer4865

+0

Sie könnten wahrscheinlich die pre_save-Methode auf dem Datetime-Feld verspotten - ein bisschen eklig, aber hey, Zeit richtig? – theWanderer4865

+0

Ich benutze Django 1.9.6 und Python 3.4 – trinchet

Antwort

6

Ok verwenden, habe ich eine Lösung gefunden, es basiert auf mock:

def mock_now(): 
    return <mock time> 

class TestMyModel(TestCase): 
    ... 
    @mock.patch('django.utils.timezone.now', mock_now) 
    def test_as_decorator(self): 
     ... 
     my_obj = MyModel.objects.create(<whatever>) 
     ... 
     # here the created_at field has the mocking time :) 

    def test_as_context_manager(self): 
     mocked_dt = datetime.datetime(2015, 9, 3, 11, 15, 0) 
     with mock.patch('django.utils.timezone.now', mock.Mock(return_value=mocked_dt)): 
      my_obj = MyModel.objects.create(<whatever>) 
      # here the created_at field has the mocking time :) 
0

auf @trinchets Antwort erweitern, hier ist es als Kontext-Manager,

from datetime import timedelta 
from django.utils import timezone 
from mock import patch, Mock 


last_week = timezone.now() - timedelta(weeks=1) 
with patch('django.utils.timezone.now', Mock(return_value=last_week)): 
    # Make your models/factories 

# Carry on with normal time 
Verwandte Themen