How to Mock the Current Date and Time in Python2020-12-20
If you’re testing Python code that relies on the current date or time, you will probably want to mock time to test different scenarios. For example, what happens when you run a certain piece of code on February 29? (A common source of bugs.)
Unfortunately such mocking is not so easy.
If you try using
unittest.mock to swap functions in the
datetime module, you’ll hit a
For example this code:
…will blow up with this
This is because the
datetime module is built in C, and
unittest.mock only supports modifying pure Python objects and functions.
So what are the alternatives?
One option is to refactor your code to use dependency injection, as suggested in this post by Haki Benita. But this can be time consuming, changes the layout of the code purely for the tests, and can be a large refactoring to impose on an otherwise working system.
Another option is to use a library that specifically mocks the date and time.
These workaround the
TypeError issue and also mock all of Python’s date and time functions at once to return consistent values.
One such library is
time-machine, which I wrote earlier this year.
With it, you can easily mock the current date and time by passing the point in time you’d like to end up at:
This works as expected:
time-machine was inspired by an earlier library called
freezegun, with some improvements in terms of performance and consistency.
For more information on the different ways you can use time-machine, see its README on PyPI.
Happy time travelling,
Working on a Django project? Check out my book Speed Up Your Django Tests which covers loads of best practices so you can write faster, more accurate tests.
One summary email a week, no spam, I pinky promise.
- Introducing time-machine, a New Python Library for Mocking the Current Time
- How I Import Python's datetime Module
© 2021 All rights reserved.