Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django tests: matching query does not exist

Tags:

I have been working on a blog app that has three regular models: Post, Category, and Comment. And now I am trying to write some tests for these models. When I run tests individually they pass without errors. But when I run tests for the test_models.py as a whole I get four errors telling me that Comment/Category matching query does not exist. I understand that this error means that django can't find the id I want in the database that's created when running the tests. My question is why am I getting these errors only when I run tests on the test_model file but not when I run the test on the test classes individually?

python manage.py test blog.tests.test_models.TestPostModel -v 2 # this command doesn't cause errors
python manage.py test blog.tests.test_models -v 2  # but this one causes 4 errors in TestPostModel

test_models.py

from blog.models import Post, Category, Comment, Recipient
from django.test import TestCase

class TestPostModel(TestCase):
@classmethod
def setUpTestData(cls):
    Post.objects.create(title="creation of the first post", body="i am the body of the first post.")

    for i in range(1, 11):
        Category.objects.create(name=f"post_category{i}")

    for i in range(1,11):
        Comment.objects.create(name=f"user{i}", email=f"user{i}@email.com", comment=f"i am comment number {i}.") 

def test_post_str_method(self):
    post = Post.objects.get(id=1) 
    self.assertTrue(isinstance(post, Post)) 
    self.assertEqual(post.__str__(), post.slug) 

def test_post_get_absolute_url(self):
    post = Post.objects.get(id=1) 
    first_post_url = f"/blog/{post.slug}" 
    self.assertEqual(first_post_url, post.get_absolute_url())  

def test_adding_categories_to_post(self):
    post = Post.objects.get(id=1) 
    for i in range(1, 11):
        post.categories.add(Category.objects.get(id=i)) # Error 1: Category matching query does not exist.
    self.assertEqual(post.categories.count(), 10)

def test_deletting_categories_from_post(self):
    post = Post.objects.get(id=1)
    for i in range(1, 11):
        post.categories.add(Category.objects.get(id=i)) # Error 2: Category matching query does not exist.

    for i in range(1, 6):
        Category.objects.filter(id=i).delete()
    self.assertEqual(post.categories.count(), 5) 

def test_adding_comments_to_post(self):
    post = Post.objects.get(id=1)
    comment =""
    for i in range(1,11):
        comment = Comment.objects.get(id=i) # Error 3: Comment matching query does not exist.
        comment.post = post
        comment.save()

    comments = Comment.objects.filter(post=post)
    self.assertEqual(comments.count(), 10)  

def test_deletting_comments_from_post(self):
    post = Post.objects.get(id=1)
    comment =""
    for i in range(1,11):
        comment = Comment.objects.get(id=i)  # Error 4: Comment matching query does not exist
        comment.post = post
        comment.save()

    Comment.objects.filter(id__in=[1, 2, 3]).delete()
    self.assertEqual(Comment.objects.count(), 7) 

class TestCategoryModel(TestCase):
@classmethod
def setUpTestData(cls):
    Category.objects.create(name="first_category")

def test_category_str_method(self):
    category = Category.objects.get(id=1)
    self.assertTrue(isinstance(category, Category)) 
    self.assertEqual(category.__str__(), category.name) 

def test_category_get_absolute_url(self):
    category = Category.objects.get(id=1)
    first_category_url = f"/blog/hashtag/{category.name}" 
    self.assertEqual(first_category_url, category.get_absolute_url())      

class TestCommentModel(TestCase):
@classmethod
def setUpTestData(cls):
    Comment.objects.create(name=f"user", email=f"[email protected]", comment=f"i am a comment.")

def test_comment_str_method(self):
    comment = Comment.objects.get(id=1)
    self.assertEqual(comment.__str__(), comment.comment) 

Thanks a lot.

like image 850
Hajar Avatar asked Feb 08 '20 18:02

Hajar


1 Answers

Django doesn't reset auto id fields for each test case. So when you run TestCommentModel and TestCategoryModel id of created object is not equal to 1.

You can save new object id in setUpTestData method and use it in test case:

class TestCategoryModel(TestCase):
    @classmethod
    def setUpTestData(cls):
        cls.obj_id = Category.objects.create(name="first_category").pk

    def test_category_str_method(self):
        category = Category.objects.get(id=self.obj_id)
        self.assertTrue(isinstance(category, Category)) 
        self.assertEqual(category.__str__(), category.name) 

    def test_category_get_absolute_url(self):
        category = Category.objects.get(id=self.obj_id)
        first_category_url = f"/blog/hashtag/{category.name}" 
        self.assertEqual(first_category_url, category.get_absolute_url())   
like image 143
neverwalkaloner Avatar answered Sep 30 '22 19:09

neverwalkaloner