Testing views in Django
This post is followed by this post. In the previous post, we go through about how to test a model in Django. Please take a look this commit if you need to grasp the idea quickly.
Testing target code
class VoteView(generic.View):
def get_queryset(self, choice_id):
return Choice.objects.get(pk=choice_id)
def post(self, request, question_id):
choice_id = request.POST.get('choice', None)
try:
queryset = self.get_queryset(choice_id)
except (KeyError, Choice.DoesNotExist):
return redirect('polls:detail', pk=question_id)
else:
queryset.votes += 1
queryset.save()
return redirect('polls:vote_results', pk=question_id)
In this post, we will see how to create some test code about this view class. At least, we need to have two test methods; get_queryset and post function. Here in the post method, we have 2 return statements. So, we should develop 3 test cases to cover every line of this view code.
At first, we need to identify what code needs to be tested like in the above. Besides, we can create more than 3 test cases with edge cases.
Snippet of test code
from django.test import TestCase
from django.test import RequestFactory
from django.urls import reverse
from model_mommy import mommy
from polls.views import VoteView
from polls.models import Choice
class TestVoteView(TestCase):
def setUp(self):
self.factory = RequestFactory()
self.question_model = mommy.make('polls.Question')
self.choice_models = mommy.make(
'polls.Choice',
question=self.question_model,
_quantity=3
)
def test_get_queryset(self):
choice = self.choice_models[0]
view = VoteView()
queryset = view.get_queryset(choice.pk)
self.assertEquals(queryset.choice_text, choice.choice_text)
def test_post_votes(self):
choice = self.choice_models[1]
votes = choice.votes + 1
request = self.factory.post(
'/some-fake/url',
data={'choice': choice.id}
)
view = VoteView.as_view()
response = view(request, question_id=choice.question.id)
new_votes = Choice.objects.get(pk=choice.id).votes
self.assertEquals(votes, new_votes)
def test_post_redirects_on_fail(self):
choice = self.choice_models[2]
request = self.factory.post(
'/some-fake/url/',
data={'choice': 500}
)
view = VoteView.as_view()
response = view(request, question_id=choice.question.id)
self.assertEquals(response.status_code, 302) # [1]
Since we identify we need 3 test cases, the TestVoteView has 3 test method and one is for initializing. The model mommy help to generate text examples. In [1], we can find the 302 status code. It means that the response fails and it does redirect. Since we make our choice model have 3 quantity, it cannot have the 500 choice index. This makes fool the original code, so it fails to response.
Leave a comment