Thursday, March 6, 2014

Unit Test Exceptions in Python

One of the goals for the next meeting was to develop tests for logging a user in to the system. This is something that is to me personally as a software developer, so I was grateful that the Django tutorial covered how to run tests in Python/Django. I did run into some difficulty though, when it came to trying to retrieve a user that was not in the database. Trying to do this would raise an exception during execution of the program.The Django framework has a method for expected exceptions called assertRaises(), but when I tried to use this, I kept getting an exception during run-time.

I thought to myself, "What's the point of this silly method? It's supposed to detect when an exception is raised, but it doesn't catch the exception before it is thrown." Here is how I was calling the assertRaises() method.
self.assertRaises(User.DoesNotExist, User.objects.get_by_natural_key('fyodor'))
Can you guess why I was still getting an exception? I'll give you a hint, it has something to do with how function argument are passed in the stack frame. Still stumped? I'll show you the solution, and maybe that will give you an idea.
with self.assertRaises(User.DoesNotExist):
    User.objects.get_by_natural_key('fyodor') 
The exception was still being raised because when function had arguments, they are placed on the stack before the function is called. This means that User.objects.get_by_natural_key() was being called before the program called the assertRaises() function was called. The program had no idea that the exception was expected at that point, so the test kept on failing.

At least, that's how I made sense of the scenario.

No comments:

Post a Comment