【问题标题】:How do I test a Django CreateView?如何测试 Django CreateView?
【发布时间】:2017-11-04 14:29:45
【问题描述】:

我想在 Django 上练习测试,我有一个想测试的 CreateView。该视图允许我创建一个新帖子,我想检查它是否可以找到没有发布日期的帖子,但首先我测试发布日期的帖子只是为了习惯语法。这就是我所拥有的:

import datetime
from django.test import TestCase
from django.utils import timezone
from django.urls import reverse
from .models import Post, Comment

# Create your tests here.
class PostListViewTest(TestCase):

    def test_published_post(self):
        post = self.client.post('/post/compose/', {'author':"manualvarado22", 'title': "Super Important Test", 'content':"This is really important.", 'published_date':timezone.now()})
        response = self.client.get(reverse('blog:post_detail'))
        self.assertContains(response, "really important")

但我明白了:

django.urls.exceptions.NoReverseMatch: Reverse for 'post_detail' with no 
arguments not found. 1 pattern(s) tried: ['post/(?P<pk>\\d+)/$']

我如何获得新创建的帖子的 pk?

谢谢!

【问题讨论】:

    标签: python django django-testing


    【解决方案1】:

    感谢您的出色回答以及一些额外的 SO 研究,我终于能够解决这个问题。这是测试的样子:

    def test_display_no_published_post(self):
            test_user = User.objects.create(username="newuser", password="securetestpassword")
            post = Post.objects.create(author=test_user, title="Super Important Test", content="This is really important.")
            response = self.client.get(reverse('blog:post_detail', kwargs={'pk':post.pk}))
            self.assertEqual(response.status_code, 404)
    

    这是创建和详细视图:

    class PostDetailView(DetailView):
        model = Post
    
        def get_queryset(self):
            return Post.objects.filter(published_date__lte=timezone.now())
    
    class PostCreateView(LoginRequiredMixin, CreateView):
        login_url = '/login/'
        redirect_field_name = 'blog/post_detail.html'
    
        form_class = PostForm
        model = Post
    

    【讨论】:

    • 你是对的@solarissmoke 我的问题不够清楚。目的是测试我的详细信息,但我的问题是尝试在测试中创建一个新帖子。感谢您的反馈。
    【解决方案2】:

    您可以直接从数据库中获取。

    注意,您不应该在测试中调用两个视图。每个测试应该只调用它实际测试的代码,所以这应该是两个单独的视图:一个调用创建视图并断言条目在数据库中,一个直接创建一个条目然后调用详细视图检查它是否显示。所以:

    def test_published_post(self):
        self.client.post('/post/compose/', {'author':"manualvarado22", 'title': "Super Important Test", 'content':"This is really important.", 'published_date':timezone.now()})
        self.assertEqual(Post.objects.last().title, "Super Important Test")
    
    def test_display_post(self):
        post = Post.objects.create(...whatever...)
        response = self.client.get(reverse('blog:post_detail', pk=post.pk))
        self.assertContains(response, "really important")
    

    【讨论】:

    • 感谢您的回答!感谢您对最佳实践的建议。我没有考虑 Post.objects.create,但我面临一个新问题,因为作者必须是授权用户,所以我从 django.contrib.auth.models 导入用户,并创建 u = User .objects.get(username="manualvarado22"),但我得到了这个:django.contrib.auth.models.DoesNotExist:用户匹配查询不存在。
    【解决方案3】:

    您想要做的测试是使用可靠的 Django Databse API 来接收创建的数据并查看您的视图是否代表这些数据。

    因为您只创建 1 模型实例并保存它。您可以通过

    获得它的pk
    model_pk = Post.objects.get(author="manualvarado22").pk
    

    然后应将此 pk 插入到您的 url 作为异常状态。

    但我也推荐 abseconded 测试,您可以通过 django 模型 API 直接检查数据库中是否存在新创建的“帖子”。 编辑:

    在测试时,django 或您正在使用的测试模块,创建一个干净的数据库仅用于测试并在测试运行后销毁它。因此,如果您想在测试时访问用户,您必须在测试设置或测试方法本身中创建用户。否则 Usertable 将为空。

    【讨论】:

    • 感谢您的回答!这对我以后的测试真的很有帮助。我现在遇到一个问题,因为作者必须是授权用户,我不确定如何在帖子创建中指定。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多