python - Django 测试客户端不创建数据库条目

标签 python django unit-testing python-3.x

我正在使用 Django 的内置测试客户端创建模拟请求来为我的 View 创建单元测试。 我正在调用的 View 应该在数据库中创建一个对象。但是,当我从测试方法中查询数据库时,对象不存在 - 它要么尚未创建,要么在从 View 返回时已被丢弃。

这是 View :

def apply_to_cmp(request, campaign_id):
    """ Creates a new Application to 'campaign_id' for request.user """
    campaign = Campaign.objects.get(pk = campaign_id)
    if not Application.objects\
                      .filter(campaign = campaign, user = request.user)\
                      .exists():
        application = Application(**{'campaign' : campaign,
                                     'user'     : request.user})
        application.save()

    return HttpResponseRedirect(request.META.get('HTTP_REFERER'))

这是调用它的测试:

def test_create_campaign_app(self):
    """ Calls the method apply_to_cmp in .views """
    c = Client()
    c.login(username = self.username, password = self.password)
    url = '/campaign/' + self.campaign.id + '/apply/'
    response = c.get(url)

    # Check whether request was successful (should return 302: redirect)
    self.assertEqual(response.status_code, 302)

    # Verify that an Application object was created
    app_count = Application.objects\
                .filter(user = self.user, campaign = self.campaign)\
                .count()
    self.assertEqual(app_count, 1)

这是运行测试的输出:

Traceback (most recent call last):
  File "/test_views.py", line 40, in test_create_campaign_app
    self.assertEqual(app_count, 1)
AssertionError: 0 != 1

肯定会调用方法 apply_to_cmp,因为 response.status_code == 302,但仍未创建 Application 对象。我做错了什么?

最佳答案

您的代码没有特别突出的问题 - 但显然您的测试用例或您正在测试的代码没有按照您的想法工作。现在是质疑您的假设的时候了。

The method apply_to_cmp is definitely being called, since response.status_code == 302

这是您的第一个假设,可能并不正确。如果您检查响应对象中的其他细节,您可能会更好地了解正在发生的事情。例如,检查 response.redirect_chain 并确认它确实重定向到您期望的位置:

response = c.get(url, follow=True)
self.assertEqual(response.redirect_chain, [<expected output here>])

其他细节呢?我看不到从您提供的代码中定义 self.username 和 self.password 的位置。您是否 100% 确定您的登录测试代码有效? c.login() 返回“True”或“False”以指示登录是否成功。在我的测试用例中,我喜欢确认登录是否成功。

login_success = c.login(username = self.username, password = self.password)
self.assertTrue(login_success)

你也可以更笼统一些。如果检查 Application.objects.filter(user=self.user, campaign=self.campaign) 什么也找不到,但是检查 Application.objects.all() 会怎样?您知道某个特定项目不在您的数据库中,但是您知道当时测试代码中数据库中存储的内容(如果有的话)吗?你期待那里有其他元素吗?检查以确认您所期望的是真实的。

我认为你可以解决这个问题,但你需要更积极地分析你的测试用例,而不是仅仅看到你的 app_count 变量不等于 1 . 检查您的响应对象,放入一些调试语句,并质疑每个假设。

关于python - Django 测试客户端不创建数据库条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24064396/

相关文章:

Python libass 还是 VapourSynth?

python - 关于 Django 和 User Auth 的问题

python - 我应该如何处理重叠批处理的 RQ 工作人员

python - Django "set.all"问题在模板中不返回任何内容

java - 导致 TestNG 测试失败?

unit-testing - Jest enzyme 浅测试没有渲染React组件的所有元素

python - 比例/百分比值

python Pandas : How to replace values in a Dataframe based on another array in conditional base

html - 谷歌字体不显示

unit-testing - curl :单线测试http/2支持