首页 > 解决方案 > Django 单元测试不会更新 BooleanField

问题描述

我有一种情况,我想为文章发布功能,我有它。问题是我无法让我的单元测试正常工作,试图将 True 发布到已发布的字段。

这是我的测试的样子。

class ArticleDetailViewTest(TestCase):

    def setUp(self):
        email = 'testuser@gmail.com'
        first_name = 'test'
        last_name = 'user'
        password = 'test15146'
        user = User.objects.create_user(email, first_name, last_name, password)
        self.client = Client()
        self.client.login(username='testuser@gmail.com', password='test15146')

    def test_can_publish_article_from_POST(self):
        other_article_two = Article.objects.create(name='Test Name One', author=User.objects.get(email='testuser@gmail.com'))
        correct_article_two = Article.objects.create(name='Test Name Two', author=User.objects.get(email='testuser@gmail.com'))

        response = self.client.post(reverse('publish_article', kwargs={'pk' : correct_article_two.pk}))

        self.assertEqual(response.status_code, 302)
        self.assertRedirects(response, f'/articles/{correct_article_two.pk}/')
        self.assertEqual(correct_article_two.published, True)

这是我的发布文章视图的样子。

def publish_article(request, pk):
    article = get_object_or_404(models.Article, pk=pk)
    if request.method == "POST":
        article.published = True
        article.save(update_fields=['published'])
        return redirect('article_detail_view', pk=article.pk)
    else:
        raise Http404

这是我的网址。

from django.urls import path

from . import views

urlpatterns = [ 
    path('', views.HomePageView.as_view(), name='home'),
    path('new/', views.ArticleCreateView.as_view(), name='article_new'),
    path('<int:pk>/', views.ArticleDetailView.as_view(), name='article_detail_view'),
    path('<int:pk>/publish/', views.publish_article, name='publish_article'),
    path('<int:pk>/unpublish/', views.unpublish_article, name='unpublish_article'),]

这是我的模型。

from django.conf import settings
from django.db import models
from django.urls import reverse
from django import forms

class Article(models.Model):
    name = models.CharField(max_length=255, blank=False)
    author = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE, 
    )
    published = models.BooleanField(default=False)

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('article_detail_view', args=[str(self.id)])

class ArticleForm(forms.ModelForm):
    class Meta:
        model = Article
        fields = ['name',]

最后,这是模板。

{% extends 'base.html' %}

{% block title %}{{ article.name }}{% endblock %}

{% block content %}

{% if article.author_id == user.pk %}
<div class="row">
    <div class="col-6 col-centered">
        <h2 class="text-center">{{ article.name }}</h2>
        <p class="text-center">by {{ article.author.first_name }} {{ article.author.last_name }}</p>
        {% if article.published %}
            <small class="form-text text-muted mb-1">This article is public.</small>
            <form method="post" action="/articles/{{ article.pk }}/unpublish/">
                {% csrf_token %}
                <input type="submit" name="unpublish" value="Unpublish Article" id="id_unpublish_button" class="btn btn-primary btn-md"/>
            </form>
        {% else %}
            <small class="form-text text-muted mb-1">This article is private.</small>
            <form method="post" action="/articles/{{ article.pk }}/publish/">
                {% csrf_token %}
                <input type="submit" name="publish" value="Publish Article" id="id_publish_button" class="btn btn-primary btn-md"/>
            </form>
        {% endif %}
    </div>
</div>
{% elif article.published %}
<div class="row">
    <div class="col-6 col-centered">
        <h2 class="text-center">{{ article.name }}</h2>
        <p class="text-center">by {{ article.author.first_name }} {{ article.author.last_name }}</p>
    </div>
</div>
{% else %}
<div class="row">
    <div class="col-6 col-centered">
        <p class="text-center">This article is private.</p>
    </div>
</div>
{% endif %}

{% endblock %}

这是我从测试中得到的错误消息。问题似乎是我可以使用 self.client.post 发布到 URL。任何帮助将不胜感激。

失败:test_can_publish_article_from_POST (articles.tests.ArticleDetailViewTest)

回溯(最后一次调用):文件“/Users/christopher.chough/article_directory/articles/tests.py”,第 126 行,在 test_can_publish_article_from_POST self.assertEqual(correct_article_two.published, True) AssertionError: False != True


在 2.340 秒内运行 17 次测试

失败(失败=1)

标签: djangodjango-formsdjango-viewsdjango-testing

解决方案


测试方法中的对象未更新。您可以在更改后使用refresh_from_db方法对其进行更新:

def test_can_publish_article_from_POST(self):
    other_article_two = Article.objects.create(name='Test Name One', author=User.objects.get(email='testuser@gmail.com'))
    correct_article_two = Article.objects.create(name='Test Name Two', author=User.objects.get(email='testuser@gmail.com'))

    response = self.client.post(reverse('publish_article', kwargs={'pk' : correct_article_two.pk}))

    correct_article_two.refresh_from_db() # Add this line

    self.assertEqual(response.status_code, 302)
    self.assertRedirects(response, f'/articles/{correct_article_two.pk}/')
    self.assertEqual(correct_article_two.published, True)

推荐阅读