2016-02-16 26 views
9

Wystąpiły problemy podczas korzystania z kodu akceptowanej odpowiedzi here.Dlaczego monkeypatch Pythona nie działa podczas importowania klasy zamiast modułu?

Kod działa w zależności od tego, w jaki sposób importuję datetime. Dlaczego tak jest? Czy można to udawać, więc działa to w obie strony?

Używam Python 3.4. Poniższy kod ilustruje problem:

import pytest 
from datetime import datetime 

mockdate = datetime(2000, 1, 1, 0, 0, 0) 

@pytest.fixture(autouse=True) 
def patch_datetime_now(monkeypatch): 
    class mydatetime: 
     @classmethod 
     def now(cls): 
      return mockdate 

    monkeypatch.setattr('datetime.datetime', mydatetime) 

def test_doesnt_work(): 
    assert datetime.now() == mockdate 

def test_works(): 
    import datetime 
    assert datetime.datetime.now() == mockdate 

Odpowiedz

11

Nawet ty nie używasz mock ramy należy spojrzeć na where to patch rozdziału. Przez

from datetime import datetime 

tworzysz nową referencję datetime.datetime w module testowym i nazwać datetime: to odniesienie, które można używać w test_doesnt_work() testu.

Przez

monkeypatch.setattr('datetime.datetime', mydatetime) 

jesteś łatanie datetime „s bezwzględnego odniesienia w module datetime: jeden używany w test_works().

+0

Dzięki, to jest przydatne. Więc, czy znasz jakiś sposób, aby działał z "datetime importu datetime" zamiast "import datetime"? – rgargente

+1

Zamiast tego powinieneś załączyć 'yourmodule.datetime'. Spójrz na fałszywe ramy: możesz dobrze "łatać" bardzo przydatne. –

+0

Utworzyłem nową odpowiedź za pomocą rozwiązania, ale nadal uważam, że to sprawiedliwe, że zaznaczam twoją odpowiedź jako zaakceptowaną. Twoje zdrowie! – rgargente

6

@ Odpowiedź Michele d'Amico wyjaśnia, dlaczego to nie działa. W ten sposób działa, jeśli chcesz używać "z datetime importu datetime" zamiast "importować datetime"

monkeypatch.setattr(__name__ + '.datetime', mydatetime)