6
@pytest.mark.parametrize("test_input,expected_output", data)
def test_send_email(test_input, expected_output):
    emails = SendEmails(email_client=MagicMock())
    emails.send_email = MagicMock()
    emails.send_new_email(*test_input)
    emails.send_email.assert_called_with(*expected_output)

I am looking to mock datetime.datetime.now() which is called in the send_new_email method. I am unsure how to do it however.

I tried creating a new datetime object

 datetime_object = datetime.datetime.strptime('Jun 1 2017  1:33PM', 
                                          '%b %d %Y %I:%M%p')

and then overriding datetime.datetime.now

datetime.datetime.now = MagicMock(return_value=datetime_object)

However, I get the error

TypeError: can't set attributes of built-in/extension type 'datetime.datetime'

This question was marked as duplicate of Python: Trying to mock datetime.date.today() but not working

Python: Trying to mock datetime.date.today() but not working

I had already tried this solution but I could not get it to work. I cannot install freezegun due to the project requirements.

I have created a new class in the test file

class NewDate(datetime.date):
@classmethod
def today(cls):
    return cls(2010, 1, 1)
datetime.date = NewDate

But I have no idea how to get the SendEmails class to use this.

user7692855
  • 1,582
  • 5
  • 19
  • 39
  • This seems to be a repost of your [last question](https://stackoverflow.com/questions/47410854/mock-datetime-datetime-now) which was already marked as a duplicate, any reason not to edit your previous question and try to get that reopened rather than repost? – EdChum Nov 21 '17 at 13:11
  • I have commented on that question and edited it. But nothing happened. The help comment says to ask a new question so I did. Just following what stackoverflow says to do. – user7692855 Nov 21 '17 at 13:21
  • The problem here is that this is a carbon copy, you need to vote to have your previous question reopened, not to post an exact duplicate – EdChum Nov 21 '17 at 13:22
  • The other question can be closed. I'm just following what the instructions say. I edited the question first and commented nothing happened. So I create this new question when I was able it. It has been upvoted so someone else must find this useful question. – user7692855 Nov 21 '17 at 13:25

1 Answers1

1

You could replace the whole class:

_FAKE_TIME = 0
class _FakeDateTime(datetime.datetime):
    @staticmethod
    def now():
        return _FAKE_TIME

then to use it:

_FAKE_TIME = whatever
datetime.datetime = _FakeDateTime

The class needs some refinements like comparison operators to make a FakeDateTime comparable to a datetime, but it should work.