Joy
Joy

Reputation: 4483

Getting error while mocking datetime.datetime.now()

I am new to Python. I am trying to mock datetime.datetime.now() but it is not working:

class Myclass:

   def update(self):

     time = datetime.datetime.now().strftime("%s")
     ...

The above function is located in mypackage/my_class.py

While writing the test as follows taking idea from this post (Trying to mock datetime.date.today(), but not working):

@patch('mypackage.my_class.Myclass.datetime')
def test_update(self, datetime_mock):
  datetime_mock.datetime.now.return_value=datetime.datetime(2020,1,1,1,1,1,1)

I am getting error as follows:

E           AttributeError: <class 'mypackage.my_class.Myclass'> does not have the attribute 'datetime'

Then I changed patching as below:

@patch('datetime')
def test_update(self, datetime_mock):
  datetime_mock.datetime.now.return_value=datetime.datetime(2020,1,1,1,1,1,1)

Now I am getting error as below:

venv/lib/python3.6/site-packages/mock/mock.py:1591: in _get_target
    target, attribute = target.rsplit('.', 1)
E   ValueError: not enough values to unpack (expected 2, got 1)

E   TypeError: Need a valid target to patch. You supplied: 'datetime'

Upvotes: 3

Views: 602

Answers (1)

Owen
Owen

Reputation: 108

You can use freeze_time from the freezegun module. I've modified update() to create a datetime string for readability in this test

class MyClass:
    def update(self):
        self.time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")

from freezegun import freeze_time


class TestMyClass:
    @freeze_time("2020-03-01 12:31")
    def test_update(self):
        my_class = MyClass()
        my_class.update()
        assert my_class.time == "2020-03-01 12:31"

Hope this helps!

Upvotes: 2

Related Questions