2017-06-25 2 views
0

J'ai un test Django où je dois moquer datetime.now(), parce que la vue qu'il utilise des tests datetime.now()Django test de simulation Datetime maintenant

J'utilise la bibliothèque maquette de Michael Foord, la version 1.0.1.
Je cherche une solution sans utiliser d'autres librairies comme freezegun. La plupart des exemples comme this et this importent le datetime et le remplacent, mais j'importe le datetime.datetime et j'essaye de le surcharger, et pour une raison quelconque cela ne fonctionne pas.

fonctionne datetime Redéfinition:

import mock 
import datetime 

class FixedDate(datetime.datetime): 

    @classmethod 
    def now(cls): 
     return cls(2010, 1, 1) 

@mock.patch('datetime.datetime', FixedDate) 
def myTest(): 
    print(datetime.datetime.now()) 

myTest() 

Mais je veux importer datetime.datetime et faire quelque chose comme ceci:

import mock 
from datetime import datetime 

class FixedDate(datetime): 

    @classmethod 
    def now(cls): 
     return cls(2010, 1, 1) 

@mock.patch('datetime', FixedDate) 
def myTest(): 
    print(datetime.now()) 

myTest() 

Cela provoque le TypeError: Besoin d'une cible valide patch. Vous avez fourni: 'datetime'.

La bibliothèque Mock indique également:

target should be a string in the form ‘package.module.ClassName’. The target is imported and the specified object replaced with the new object, so the target must be importable from the environment you are calling patch from.

est-il un moyen de chemin que le datetime et non le datetime.datetime?

Nb. J'ai vu aussi this exemple, mais cela ne fonctionnera pas pour moi, parce que je n'ai pas une fonction qui renvoie le datetime, mais ma vue utilise datetime.now()

+2

pourquoi l'aide datetime permettent de remplacer vous datetime = FixedDate? –

+0

erreur. l'a enlevé. – Kemeia

Répondre

1

Vous devriez patch objets dans le module que vous testez , pas dans le module avec des tests.

exemple de travail minimale en fonction de votre code:

app.py

from datetime import datetime 

def my_great_func(): 
    # do something 
    return datetime.now() 

tests.py (remarquez comment datetimedansapp.py est patché)

from datetime import datetime 
from unittest import mock 
from app import my_great_func 

@mock.patch('app.datetime') 
def test_my_great_func(mocked_datetime): 
    mocked_datetime.now.return_value = datetime(2010, 1, 1) 
    assert my_great_func() == datetime(2010, 1, 1) 

résultats d'exécution des tests:

$ pytest -vvv tests.py 
======================= test session starts ========================= 
platform linux -- Python 3.5.2, pytest-3.2.1, py-1.4.34, pluggy-0.4.0 
cachedir: .cache 
rootdir: /home/kris/projects/tmp, inifile: 
plugins: mock-1.6.2, celery-4.1.0 
collected 1 item             

tests.py::test_my_great_func PASSED 

==================== 1 passed in 0.00 seconds ======================= 
+0

Merci pour la réponse! Je n'utilise pas Python3 avec la bibliothèque unittest intégrée, mais Python2.7 avec la bibliothèque de simulation de Michael Foord Suite à votre réponse, j'ai essayé d'importer @ mock.patch ('app.datetime'), mais cela a entraîné une erreur . – Kemeia

+0

@marmai: pourriez-vous poster une erreur? – kchomski

+0

En fait, je l'ai fait fonctionner avec Python 2.7, le seul problème est que vous surchargez l'objet datetime entier, pas seulement datetime.now, ce qui rend l'utilisation de l'objet datetime à d'autres fins (datetime (2017, 8, 22) ou datetime .timedelta()) impossible – Kemeia