[Python] 파이썬 : datetime.date.today ()를 조롱하려고했지만 작동하지 않습니다.


Answers

또 다른 옵션은 https://github.com/spulec/freezegun/

그것을 설치하십시오 :

pip install freezegun

그리고 그것을 사용하십시오 :

from freezegun import freeze_time

@freeze_time("2012-01-01")
def test_something():

    from datetime import datetime
    print(datetime.now()) #  2012-01-01 00:00:00

    from datetime import date
    print(date.today()) #  2012-01-01

또한 다른 모듈의 메소드 호출에서 다른 datetime 호출에 영향을줍니다.

other_module.py :

from datetime import datetime

def other_method():
    print(datetime.now())    

main.py :

from freezegun import freeze_time

@freeze_time("2012-01-01")
def test_something():

    import other_module
    other_module.other_method()

그리고 마지막으로:

$ python main.py
# 2012-01-01
Question

아무도 왜 이것이 작동하지 않는지 말해 줄 수 있습니까?

>>> import mock
>>> @mock.patch('datetime.date.today')
... def today(cls):
...  return date(2010, 1, 1)
...
>>> from datetime import date
>>> date.today()
datetime.date(2010, 12, 19)

아마도 누군가가 더 좋은 방법을 제안 할 수 있을까요?




Daniel G의 솔루션에 추가하려면 다음을 수행하십시오.

from datetime import date

class FakeDate(date):
    "A manipulable date replacement"
    def __new__(cls, *args, **kwargs):
        return date.__new__(date, *args, **kwargs)

이것은 인스턴스 생성시 일반 datetime.date 객체를 반환하지만 변경할 수있는 클래스를 만듭니다.

@mock.patch('datetime.date', FakeDate)
def test():
    from datetime import date
    FakeDate.today = classmethod(lambda cls: date(2010, 1, 1))
    return date.today()

test() # datetime.date(2010, 1, 1)






Daniel G 솔루션을 기반으로 다음 접근법을 사용할 수 있습니다. 이것은 isinstance(d, datetime.date) 하여 유형 검사를 중단하지 않는 이점이 있습니다.

import mock

def fixed_today(today):
    from datetime import date

    class FakeDateType(type):
        def __instancecheck__(self, instance):
            return isinstance(instance, date)

    class FakeDate(date):
        __metaclass__ = FakeDateType

        def __new__(cls, *args, **kwargs):
            return date.__new__(date, *args, **kwargs)

        @staticmethod
        def today():
            return today

    return mock.patch("datetime.date", FakeDate)

기본적으로 C 기반 datetime.date 클래스를 원래의 datetime.date 인스턴스를 생성하고 원래 datetime.date 와 똑같은 isinstance() 쿼리에 응답하는 자체 Python 하위 클래스로 대체합니다.

테스트에서 컨텍스트 관리자로 사용하십시오.

with fixed_today(datetime.date(2013, 11, 22)):
    # run the code under test
    # note, that these type checks will not break when patch is active:
    assert isinstance(datetime.date.today(), datetime.date)

유사한 접근법은 datetime.datetime.now() 함수를 조롱하는 데 사용될 수 있습니다.




나는 며칠 전에 같은 상황에 직면했고, 나의 해결책은 모듈에서 함수를 정의하고 테스트 해보는 것이었다.

def get_date_now():
    return datetime.datetime.now()

오늘 나는 FreezeGun 에 대해 알아 FreezeGun ,이 사건을 아름답게 덮을 것 같습니다.

from freezegun import freeze_time
import datetime
import unittest


@freeze_time("2012-01-14")
def test():
    assert datetime.datetime.now() == datetime.datetime(2012, 1, 14)



나를 위해 가장 쉬운 방법은 이렇게하는 것입니다.

from unittest import patch, Mock

def test():
    datetime_mock = Mock(wraps=datetime)
    datetime_mock.now = Mock(return_value=datetime(1999, 1, 1)
    patch('target_module.datetime', new=datetime_mock).start()