In this post, we looks into unit testing some calendar utilities in Python.
A requirement for unit testing those is to “mock” current date and time, i.e., overriding those returned by
now methods with some specific date values (e.g., a date in future).
What is a big deal about calendar utitlities? There are surprisingly many types of calendar. Some of them are: regular calendar, lunar calendar, fiscal calendar, retail calendar. See here for more information of each calendar type. Out of the above calendar types, retail calendar seems to have more complex rules. However, this calendar type is frequently used in industries like retail and manufacturing for ease of planning around it.
Mocking current time in Python
Due to retail calendar’s desirable characteristics, we may have code that work with retail calendars in commercial applications eventually. I ended up working with a utility Python module for retail calendar with functions which return values based on current time/date. For example, a utility function to check if a given date is in the current 544 year works like this:
1 2 3 4 5 6
Some utility functions in that module are even more complicated than this example function.
For those, I think calling
now inside those functions is a bad design.
They are essentially another variable in those functions (i.e., when do you run?), and it is better to expose that variable as an input parameter.
In addition, being able to specify what “today” or “now” value is will make automated unit testing easier.
For example, I want to know how my Python programs work if it runs on a particular date, such as end of retail year July 29, 2006.
A probably better, more testable function would be something like this.
1 2 3 4 5
However, in reality, you sometimes have to live with the original utility Python module.
Then, the workaround for unit testing is to “mock” current date and time, i.e., overriding those returned by
now methods with some specific date values.
In Python, it can be done by using some mocking framework, such as illustrated here.
Fortunately, my life was made even easier with
freezegun on Mac OSX, simply run
freezegun library, I can easily specify my “current date” as “July 29, 2006” by adding the following decorator with some string “2006-07-29” for that date.
1 2 3 4 5 6
For full usage of
freezegun, refer to its quickstart guide.
It should be noted that
freezegun can mock
datetime calls from other modules and it works great for testing with
However, you might encounter some occasional failures in your unit tests when working with
From my personal experience, in those cases, note that time zones must be accounted for when mocking with
time module by specifying
tz_offset in the decorator