How to mock/set system date in pytest?

删除回忆录丶 提交于 2019-12-06 23:23:39

问题


In some of my tests I am having a problem that they fail on Travis because of time and time zone problems, so I want to mock system time for my test. How can I do this?


回答1:


AFAIK, you can't mock builtin methods.

One approach I have often done is to change my code a bit to not use datetime directly to obtain the date, but a wrapper function somewhere:

# mymodule.py

def get_today():
   return datetime.date.today()

This makes it trivial to just mock it in your test:

def test_something():
    with mock.patch('mymodule.get_today', return_value=datetime.date(2014, 6, 2)):
        ...

You can also use the freezegun module.




回答2:


There are two ways you can accomplish that:

  1. Create function which you will call instead of datetime.datetime.now() as suggested by Bruno, but here is different implementation:

    import os
    import datetime
    
    def mytoday():
     if 'MYDATE' in os.environ:
         return datetime.datetime.strptime(os.getenv('MYDATE'), '%m-%d-%Y').date()
     else:
         return datetime.date.today()
    

    Then, in your test, you just monkeypatch environment variable:

    import datetime
    
    def test_patched_date(monkeypatch):
        monkeytest.setenv('MYDATE', '05-31-2014')
        assert datetime.date.today() == datetime.date(2014, 5, 31)
    
  2. Monkeypatch the datetime function:

    import datetime
    import pytest
    
    FAKE_TIME = datetime.datetime(2020, 12, 25, 17, 05, 55)
    
    @pytest.fixture
    def patch_datetime_now(monkeypatch):
    
        class mydatetime:
            @classmethod
            def now(cls):
                return FAKE_TIME
    
        monkeypatch.setattr(datetime, 'datetime', mydatetime)
    
    
    def test_patch_datetime(patch_datetime_now):
        assert datetime.datetime.now() == FAKE_TIME
    



回答3:


@Brian-Kruger's answer is the best one. I've voted to undelete it. In the meantime...

Use freezegun (repo).

From the README:

from freezegun import freeze_time

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


来源:https://stackoverflow.com/questions/23988853/how-to-mock-set-system-date-in-pytest

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!