Trying to mock, but not working

Can anyone tell me why this isn’t working?

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

Perhaps someone could suggest a better way?

Solution #1:

There are a few problems.

First of all, the way you’re using mock.patch isn’t quite right. When used as a decorator, it replaces the given function/class (in this case, with a Mock object only within the decorated function. So, only within your today() will be a different function, which doesn’t appear to be what you want.

What you really want seems to be more like this:

def test(): = date(2010, 1, 1)

Unfortunately, this won’t work:

>>> test()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "build/bdist.macosx-10.6-universal/egg/", line 557, in patched
  File "build/bdist.macosx-10.6-universal/egg/", line 620, in __enter__
TypeError: can't set attributes of built-in/extension type ''

This fails because Python built-in types are immutable – see this answer for more details.

In this case, I would subclass myself and create the right function:

import datetime
class NewDate(
    def today(cls):
        return cls(2010, 1, 1) = NewDate

And now you could do:

NewDate(2010, 1, 1)
Respondent: Daniel G

Solution #2:

Another option is to use

Install it:

pip install freezegun

And use it:

from freezegun import freeze_time

def test_something():

    from datetime import datetime
    print( #  2012-01-01 00:00:00

    from datetime import date
    print( #  2012-01-01

It also affects other datetime calls in method calls from other modules:

from datetime import datetime

def other_method():

from freezegun import freeze_time

def test_something():

    import other_module

And finally:

$ python
# 2012-01-01
Respondent: Mehdi Behrooz

Solution #3:

For what it’s worth, the Mock docs talk about specifically, and it’s possible to do this without having to create a dummy class:

>>> from datetime import date
>>> with patch('') as mock_date:
... = date(2010, 10, 8)
...     mock_date.side_effect = lambda *args, **kw: date(*args, **kw)
...     assert == date(2010, 10, 8)
...     assert, 6, 8) == date(2009, 6, 8)
Respondent: kpup

Solution #4:

I guess I came a little late for this but I think the main problem here is that you’re patching directly and, according to the documentation, this is wrong.

You should patch the reference imported in the file where the tested function is, for example.

Let’s say you have a file where you have the following:

import datetime

def get_today():

then, in your test, you should have something like this

import datetime
import unittest

from functions import get_today
from mock import patch, Mock

class GetTodayTest(unittest.TestCase):

    def test_get_today(self, datetime_mock): = Mock(return_value=datetime.strptime('Jun 1 2005', '%b %d %Y'))
        value = get_today()
        # then assert your thing...

Hope this helps a little bit.

Respondent: iferminm

Solution #5:

To add to Daniel G’s solution:

from datetime import date

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

This creates a class which, when instantiated, will return a normal object, but which is also able to be changed.

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

test() #, 1, 1)
Respondent: eternicode

Solution #6:

I faced the same situation a couple of days ago, and my solution was to define a function in the module to test and just mock that:

def get_date_now():

Today I found out about FreezeGun, and it seems to cover this case beautifully

from freezegun import freeze_time
import datetime
import unittest

def test():
    assert == datetime.datetime(2012, 1, 14)
Respondent: Hito_kun

Solution #7:

The easiest way for me is doing this:

import datetime
from unittest.mock import Mock, patch

def test():
    datetime_mock = Mock(wraps=datetime.datetime) = datetime.datetime(1999, 1, 1)
    with patch('datetime.datetime', new=datetime_mock):
        assert == datetime.datetime(1999, 1, 1)

CAUTION for this solution: all functionality from datetime module from the target_module will stop working.

Respondent: frx08

Solution #8:

You can use the following approach, based on Daniel G solution. This one has advantage of not breaking type checking with isinstance(d,

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)

        def today():
            return today

    return mock.patch("", FakeDate)

Basically, we replace C-based class with our own python subclass, that produces original instances and responds to isinstance() queries exactly as native

Use it as context manager in your tests:

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

Similar approach can be used to mock function.

Respondent: Andrey Lebedev

Solution #9:

Generally speaking, you would have datetime or perhaps imported into a module somewhere. A more effective way of mocking the method would be to patch it on the module that is importing it. Example:

from datetime import date

def my_method():

Then for your test, the mock object itself would be passed as an argument to the test method. You would set up the mock with the result value you want, and then call your method under test. Then you would assert that your method did what you want.

>>> import mock
>>> import a
>>> @mock.patch('')
... def test_my_method(date_mock):
... =
...     result = a.my_method()
...     print result
...     assert == result
>>> test_my_method()

A word of warning. It is most certainly possible to go overboard with mocking. When you do, it makes your tests longer, harder to understand, and impossible to maintain. Before you mock a method as simple as, ask yourself if you really need to mock it. If your test is short and to the point and works fine without mocking the function, you may just be looking at an internal detail of the code you’re testing rather than an object you need to mock.

Respondent: jpmc26

Solution #10:

Here’s another way to mock with an added bonus that the rest of datetime functions continue to work, as the mock object is configured to wrap the original datetime module:

from unittest import mock, TestCase

import foo_module

class FooTest(TestCase):

    @mock.patch(f'{foo_module.__name__}.datetime', wraps=datetime)
    def test_something(self, mock_datetime):
        # mock only =, 3, 15)
        # other calls to datetime functions will be forwarded to original datetime

Note the wraps=datetime argument to mock.patch() – when the foo_module uses other datetime functions besides they will be forwarded to the original wrapped datetime module.

Respondent: mrts

Solution #11:

We can use pytest-mock ( mocker object to mock datetime behaviour in a particular module

Let’s say you want to mock date time in the following file

# File path - source_dir/x/
import datetime

def name_function():
     name =
     return f"name_{name}"

In the test function, mocker will be added to the function when test runs

def test_name_function(mocker):
     mocker.patch('x.a.datetime') = datetime(2019, 1, 1)

     actual = name_function()

     assert actual == "name_2019-01-01"

Solution #12:

Several solutions are discussed in In summary:

Mock object – Simple and efficient but breaks isinstance() checks:

target = datetime.datetime(2009, 1, 1)
with mock.patch.object(datetime, 'datetime', mock.Mock(wraps=datetime.datetime)) as patched: = target

Mock class

import datetime
import mock

real_datetime_class = datetime.datetime

def mock_datetime_now(target, dt):
    class DatetimeSubclassMeta(type):
        def __instancecheck__(mcs, obj):
            return isinstance(obj, real_datetime_class)

    class BaseMockedDatetime(real_datetime_class):
        def now(cls, tz=None):
            return target.replace(tzinfo=tz)

        def utcnow(cls):
            return target

    # Python2 & Python3 compatible metaclass
    MockedDatetime = DatetimeSubclassMeta('datetime', (BaseMockedDatetime,), {})

    return mock.patch.object(dt, 'datetime', MockedDatetime)

Use as:

with mock_datetime_now(target, datetime):
Respondent: eddygeek

Solution #13:

CPython actually implements the datetime module using both a pure-Python Lib/ and a C-optimized Modules/_datetimemodule.c. The C-optimized version cannot be patched but the pure-Python version can.

At the bottom of the pure-Python implementation in Lib/ is this code:

    from _datetime import *  # <-- Import from C-optimized module.
except ImportError:

This code imports all the C-optimized definitions and effectively replaces all the pure-Python definitions. We can force CPython to use the pure-Python implementation of the datetime module by doing:

import datetime
import importlib
import sys

sys.modules["_datetime"] = None

By setting sys.modules["_datetime"] = None, we tell Python to ignore the C-optimized module. Then we reload the module which causes the import from _datetime to fail. Now the pure-Python definitions remain and can be patched normally.

If you’re using Pytest then include the snippet above in and you can patch datetime objects normally.

Respondent: GrantJ

Solution #14:

Maybe you could use your own “today()” method that you will patch where needed. Example with mocking utcnow() can be found here:

Solution #15:

I implemented @user3016183 method using a custom decorator:

def changeNow(func, newNow = datetime(2015, 11, 23, 12, 00, 00)):
    """decorator used to change in the tested function."""
    def retfunc(self):                             
        with mock.patch('mymodule.datetime') as mock_date:                         
   = newNow
            mock_date.side_effect = lambda *args, **kw: datetime(*args, **kw)
    return retfunc

I thought that might help someone one day…

Respondent: DainDwarf

Solution #16:

It’s possible to mock functions from datetime module without adding side_effects

import mock
from datetime import datetime
from where_datetime_used import do

initial_date = datetime.strptime('2018-09-27', "%Y-%m-%d")
with mock.patch('where_datetime_used.datetime') as mocked_dt: = initial_date
Respondent: Daniil Mashkin

Solution #17:

For those of you using pytest with mocker here is how I mocked which is very similar to the original question.

    datetime_mock = mocker.patch("blackline_accounts_import.datetime",),3,11,6,2,0,0)

    now == function_being_tested()  # run function

    assert now == datetime.datetime(2019,3,11,6,2,0,0)

Essentially the mock has to be set to return the specified date. You aren’t able to patch over datetime’s object directly.

Respondent: Daniel Butler

Solution #18:

I made this work by importing datetime as realdatetime and replacing the methods I needed in the mock with the real methods:

import datetime as realdatetime

def test_method(self, mock_datetime): = = realdatetime.datetime(2019, 8, 23, 14, 34, 8, 0)
Respondent: Adam McKenna

Solution #19:

You can mock datetime using this:

In the module

import datetime

class ShowTime:
    def current_date():

In your

from unittest import TestCase, mock
import datetime

class TestShowTime(TestCase):
    def setUp(self) -> None: = sources.ShowTime()

    def test_current_date(self, date_mock): = datetime.datetime(year=2019, month=10, day=1)
        current_date =
        self.assertEqual(current_date, '2019-10-01')
Respondent: MTMobile

The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .

Leave a Reply

Your email address will not be published.