0

I am new to testing and am trying to run the following tests but I get a 404 assertion error because the method that tries to reverse the url cannot find the category that had been created in the setUp method. I can create categories in the browser using the superuser with no problem and the url responds with 200 status. Could you help me understand what I am doing wrong?

Test:

from __future__ import unicode_literals
from django.core.urlresolvers import reverse
from django.test import TestCase
from django.contrib.auth.models import User
from cataloger.models import Category

class CatalogerCategoriesTests(TestCase):

    def setUp(self):
       tom = User.objects.create_user(username="tom", password="1234567")
       Category.objects.create(name="cell phone", 
                            description="current cell phone types in the market.",
                            created_by=tom)

    def test_category_page_success_status_code(self):
       url = reverse('category_items', kwargs={'pk': 1})
       response = self.client.get(url)
       self.assertEquals(response.status_code, 200)

Fail:

Traceback (most recent call last):
  File "/home/ubuntu/workspace/cataloger/tests_categories.py", line 48, in test_category_page_success_status_code
    self.assertEquals(response.status_code, 200)
AssertionError: 404 != 200

Models:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models
from django.contrib.auth.models import User


class Category(models.Model):
    name = models.CharField(max_length=50)
    description = models.CharField(max_length=300)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(null=True)
    created_by = models.ForeignKey(User, related_name="categories")

Views:

from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.models import User
from cataloger.models import Category

def category_items(request, pk):
    category = get_object_or_404(Category, pk=pk)
    return render(request, 'category_items.html', {'category': category})

urls:

from django.conf.urls import url
from . import views

urlpatterns = [
        url(r'^cataloger/$', views.cataloger, name='cataloger'),
        url(r'^cataloger/categories/(?P<pk>\d+)/$', views.category_items, name='category_items')
    ]
2
  • Please post urls.py Commented Dec 18, 2017 at 1:58
  • @Ykh I have added the urls.py Commented Dec 18, 2017 at 2:11

2 Answers 2

2

The pk of the object might not always be 1 depending upon the test structure and DB. The pk of the Category instance should be used explicitly.

from __future__ import unicode_literals
from django.core.urlresolvers import reverse
from django.test import TestCase
from django.contrib.auth.models import User
from cataloger.models import Category

class CatalogerCategoriesTests(TestCase):
    def setUp(self):
        tom = User.objects.create_user(username="tom", password="1234567")
        self.category = Category.objects.create(
            name="cell phone", 
            description="current cell phone types in the market.",
            created_by=tom
        )

    def test_category_page_success_status_code(self):
        url = reverse('category_items', kwargs={'pk': self.category.pk})
        response = self.client.get(url)
        self.assertEquals(response.status_code, 200)
Sign up to request clarification or add additional context in comments.

1 Comment

thank you! it worked. I just had to do a minor edit to "self.category" attribute of the "setUp" method.
1

@Stuart Dines explains very well. You should match pk for urls.

Or if you just want to know that model instance created well, just try self.assertIsInstance(...)

def setUp(self):
   tom = User.objects.create_user(username="tom", password="1234567")
   category = Category.objects.create(name="cell phone", 
                        description="current cell phone types in the market.",
                        created_by=tom)

def test_if_category_instance_made(self):
    self.assertIsInstance(self.category, Category)

Also I recommend model mommy for easy testing django models. It automatically generate random model (also put test data possible) and make really easy to testing your model!

This is example using model_mommy for your test code

from model_mommy import mommy

class CatalogerCategoriesTests(TestCase):

    def setUp(self):
        self.tom = mommy.make("User")
        self.category = mommy.make("Category", user=self.user)

    def test_if_category_instance_made(self):
        self.assertIsInstance(self.category, Category)

    def test_category_page_success_status_code(self):
        url = reverse('category_items', kwargs={'pk': self.category.pk})
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

1 Comment

thanks for recommending this library. I was looking for something that resembles FactoryGirl in RoR.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.