【问题标题】:Django tests: matching query does not existDjango 测试:匹配的查询不存在
【发布时间】:2020-02-08 18:32:24
【问题描述】:

我一直在开发具有三个常规模型的博客应用程序:PostCategoryComment。现在我正在尝试为这些模型编写一些测试。 当我单独运行测试时,它们会毫无错误地通过。但是,当我对整个 test_models.py 运行测试时,我收到四个错误,告诉我 Comment/Category matching query does not exist. 我明白这个错误意味着 django 在运行测试时创建的数据库中找不到我想要的 id . 我的问题是为什么我只有在 test_model 文件上运行测试时才会出现这些错误,而在单独对测试类运行测试时却没有?

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"user@email.com", comment=f"i am a comment.")

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

非常感谢。

【问题讨论】:

    标签: python django testing


    【解决方案1】:

    Django 不会为每个测试用例重置自动 id 字段。所以当你运行TestCommentModelTestCategoryModel 时,创建对象的id 不等于1。

    您可以在setUpTestData 方法中保存新的对象id 并在测试用例中使用它:

    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())   
    

    【讨论】:

    • 现在所有测试都通过了。非常感谢。
    猜你喜欢
    • 2021-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-28
    • 2020-10-15
    • 1970-01-01
    相关资源
    最近更新 更多