You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django投票清零视图测试失败:AssertionError问题如何解决?

问题描述

我跟随Django官方教程学习基础开发,为应用新增了可清零特定Question所有投票的nullask视图,该功能运行正常。但编写测试用例验证投票清零效果时,出现AssertionError: 10 != 0错误,断言投票未成功清零。尝试用response.context['question']获取对象时触发报错,请问如何修正测试用例?

相关代码如下:

视图代码

def nullask(request, question_id):
    question=get_object_or_404(Question, pk = question_id)
    if request.method == "GET":
        return render(request, "polls/nullifyask.html", {"question":question})
    else:
        for i in question.choice_set.all():
            i.votes = 0
            i.save()
        return HttpResponseRedirect(reverse("polls:index"))

测试代码(原错误版本)

class NullingViewTest(TestCase):
    def test_nulling(self):
        q=create_question(text="Future", days=-1)
        choice=q.choice_set.create(choice_text="1", votes=10)
        response=self.client.post(reverse('polls:nullask', args=(q.id,)))
        self.assertEqual(choice.votes, 0)

模板代码(nullifyask.html)

<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="utf-8" />
    <title>Nullyfying of {{question_id}}</title>
  </head>
  <body>
    <form method="post">
      {% csrf_token %}
        <legend><h1>Do you want to nullify votes of question {{question.text}}</h1></legend>
        <input type="submit" name="Yes" value="Yes!">
    </form>
  </body>
</html>

模型代码

class Question(models.Model):
    text=models.CharField(max_length=200)
    productiondate=models.DateTimeField("date published")

    def was_published_recently(self):
        return self.productiondate >= timezone.now() - datetime.timedelta(days=1) and self.productiondate<timezone.now()
    def __str__(self):
        return self.text
    class Meta:
        permissions=(( "can_nullify","User can nullify votes" ),)
class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
    def votesx2(self):
        return self.votes*2
    def __str__(self):
        return self.choice_text
解决方案

核心问题

  • 测试中的choice是修改前从数据库取出的内存实例,视图修改数据库后,该实例不会自动同步最新数据,所以choice.votes仍为初始的10,导致断言失败。
  • response.context['question']报错是因为视图返回的是HttpResponseRedirect,重定向响应不包含上下文数据。

修正方法(二选一即可)

方法1:重新从数据库获取Choice实例

发送POST请求后,通过查询数据库拿到更新后的对象再断言:

class NullingViewTest(TestCase):
    def test_nulling(self):
        q=create_question(text="Future", days=-1)
        choice=q.choice_set.create(choice_text="1", votes=10)
        self.client.post(reverse('polls:nullask', args=(q.id,)))
        # 重新查询数据库获取最新的Choice对象
        updated_choice = Choice.objects.get(pk=choice.pk)
        self.assertEqual(updated_choice.votes, 0)

方法2:刷新现有实例

调用refresh_from_db()方法,让内存中的实例同步数据库最新状态:

class NullingViewTest(TestCase):
    def test_nulling(self):
        q=create_question(text="Future", days=-1)
        choice=q.choice_set.create(choice_text="1", votes=10)
        self.client.post(reverse('polls:nullask', args=(q.id,)))
        # 刷新实例数据
        choice.refresh_from_db()
        self.assertEqual(choice.votes, 0)

内容的提问来源于stack exchange,提问作者MrAdvocat2019

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 17:05:00