2013-11-08

Mock python datetime.datetime.now (or built-in objects declared in C)

With the Python programming language you can patch almost everything with just few lines of code. It's quite easy, unless you are going to patch built-in objects declared in C (for example datetime.datetime.now, datetime.date.today, etc).

So what you can do if you have to mock this kind of methods in your tests?
One possible option is to use the forbiddenfruit library (https://github.com/clarete/forbiddenfruit).
This project aims to help you reach heaven while writing tests, but it may lead you to hell if used on production code.
It basically allows you to patch built-in objects, declared in C through python.
Here you can find a plone.app.testing layer definition that helps you to patch the datetime.datetime.now method:
class FakeDateTime(PloneSandboxLayer):

    defaultBases = (PLONE_FIXTURE,)

    def setUp(self):
        import datetime
        original_now = datetime.datetime.now
        first_now = original_now()
        delta = datetime.datetime(first_now.year + 1, 1, 1, 0, 0, 0) - first_now
        def fake_now(self):
            now = original_now()
            return now + delta
        curse(datetime.datetime, 'now', classmethod(fake_now))

    def tearDown(self):
        import datetime
        from forbiddenfruit import reverse
        reverse(datetime.datetime, 'now')
Links: