Search code examples
python-2.7django-admintdddjango-testingdjango-unittest

Django - Unit Testing an AdminForm


I am very new to unit testing and am probably doing something wrong, but when I simulate a post to update a model via the admin backend it seems like my save_model method in my AdminForm isn't being called. I am trying to test this method - what am I doing wrong?

My second, less relevant question is in general how can I make sure a method is being called when I use unit testing? Is there some way to list all the methods that were hit?

Below is the code my test is running. In my save_model method in my AdminForm for this model, I set this model's foobar attribute to the username of the currently signed in user. Below is my test:

self.client = Client()
self.client.login(username='username',password='password')
# self.dict is a dictionary of field names and values for mymodel to be updated
response = self.client.post('/admin/myapp/mymodel/%d/' % self.mymodel.id, self.dict)
self.assertEqual(response.status_code,200) # passes
self.assertEqual(self.mymodel.foobar,'username') # fails
self.client.logout()

It fails because it says that self.mymodel.foobar is an empty string. That was what it should have been before the update. No value for foobar is passed in the self.dict but my save_model method is designed to set it on its own when the update happens. It is also worth noting that my code works correctly and save_model seems to work fine, just my test is failing. Since I am a total noob at TDD, I'm sure the issue is with my test and not my code. Thoughts?


Solution

  • From the code it looks like the problem is that, after posting the form, you don't reload self.mymodel from the database. If you hold a reference to a model object stored in the database, and one or more of the fields on that object is changed in the database, then you will need to reload the object from the database to see the updated values. As detailed in this question, you can do this with something like:

    self.mymodel = MyModelClass.objects.get(id=self.mymodel.id)
    

    To answer your second question, probably the most useful way to see what is happening would be to use logging to output what is happening in your save_model method - this will not only help you debug the issue during testing, but also if you encounter any issues in this method when running your application. The django guide to logging gives an excellent introduction:

    https://docs.djangoproject.com/en/dev/topics/logging/