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
相关产品推荐
相关产品推荐

