My Online Life

Rss

Twitter 4 hours, 46 minutes ago

Screencasts are such a timesink...one down, trying to get one more done tonight so I can launch my series tomorrow and have a buffer on it..

Twitter 7 hours, 38 minutes ago

Some great speechs tonight at the convention. Here's to hope winning out and ignorance not pervade this election like previous ones!

Twitter 9 hours, 10 minutes ago

@tswicegood I saw Bill speak at my college during the primaries and it was amazing. He's quite a speaker.

delicious 10 hours, 2 minutes ago
Twitter 15 hours, 35 minutes ago

@LorenDavie Kinda, The math/symbol stuff on http://tinyurl.com/2cxmmw really made it click for me.

delicious 15 hours, 49 minutes ago

An Introduction to Python - Iterators

Google Reader 15 hours, 53 minutes ago

Ubiquity: Firefox Gets its Quicksilver On

Twitter 16 hours, 13 minutes ago

Really starting to "get" python, it's a wonderful language :)

Twitter 17 hours, 25 minutes ago

Wow, had a billing issue (on my side) with slicehost, within an hour I had 2 responses and the problem was fixed! well done.

Welcome to the home of Eric Holscher on the web. There isn't a huge amount of stuff here except for my blog postings. I have a couple projects I'm working on that will be thrown up here soonish. In the meantime, enjoy the blog!

Latest Blog Post

Using Mock objects in Django for testing the current date

14 August 2008

Today I ran into a fun problem when writing template tags at work. (I'll write another post later on the fun-ness that is testing of template tags :) In ellington we have some templatetags that test for the current time of day. ifmorning, ifnight and so on. These template tags are using datetime.datetime.now() to check to see if the time is within a certain range. This is impossible to test in a standard way without doing some hacking on the datetime.datetime object.

The solution is actually pretty easy. Let me warn, although this is the correct solution in this case, monkeypatching is generally BAD. You don't want to just be playing around with python or django's stdlib and breaking things for other people. With that warning, let me show you how I went about doing this.

This code is called in this fashion:

import unittest class LoadDateutil(TemplateTestCase): def test_load(self): olddatetime = datetime.datetime datetime.datetime = make_datetime(5) self.assertEqual(self.render(u'{% load dateutil %}{% ifnight %}Hi{% endifnight %}'), u'') datetime.datetime = olddatetime

Now let me explain what all is going on here. TemplateTestCase is an internal base class for doing templatetag tests. This will probably be released (by me or Matt Croydon) sometime soonish.

The first thing you want to make sure you do is leave everything how you found it. So before we go about editing the datetime.datetime object, we save it into olddatetime, and once we are done with the test, we return datetime.datetime back to its original value. In the middle of the test, we are calling datetime.datetime = make_datetime(5) which is returning a datetime.datetime object that has it's now() method overwritten. The argument to make_datetime is the hour of the day you want to represent.

Let's take a look at how make_datetime is working:

import datetime def make_datetime(hour): class MockDatetime(datetime.datetime): @classmethod def now(cls): return datetime.datetime(2007, 1, 1, hour) return MockDatetime

This code is creating the MockDatetime class, and then defining the now() method. The @classmethod decorator must be used because the now() method is a class method. Then the now() method simply returns a datetime.datetime object with the correct hour in it.

This is pretty simple, and is the correct and best way to do testing of this nature. I hope this is helpful to someone out there :) Also note that these methods are not django specific, and can be used in anything with python.

As a caveat, make sure that the templatetag code you are running this test against is importing the datetime module, and not datetime.datetime, because in that instance this code will not work (because the code we're overwriting will be re-imported in the templatetag (as far as I can tell))

Thanks to Malcolm for helping me with this.

More blog postings