Ich bin mit einem seltsamen Fehler konfrontiert, in dem ein Django-Test, den ich geschrieben habe, um die Antwort einer Ansicht zu testen, mir nicht das erwartete Verhalten gibt.Testclient wirft nicht erwarteten 404-Fehler
Betrachten Sie das folgende Modell für eine einfache Blogging-Anwendung:
class Post(models.Model):
"""Represents a Post in the blogging system."""
# is the post published or in draft stage?
STATUS_CHOICES = (
('draft', 'Draft'),
('published', 'Published'),
('deleted', 'Deleted'),
)
# the default mode for posts
DRAFT = STATUS_CHOICES[0][0]
title = models.CharField(max_length=250, null=True)
slug = models.SlugField(max_length=200, blank=True)
text = models.TextField(null=True)
last_modified = models.DateTimeField(default=timezone.now)
date_published = models.DateTimeField(default=timezone.now, null=True)
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default=DRAFT)
category = models.ForeignKey('Category', null=True)
author = models.ForeignKey('Author', null=True)
class Meta:
ordering = ('-date_published',)
@property
def truncated_text(self):
if len(self.text) > 200:
return '{} . . .'.format(self.text[0:300])
else:
return self.text
def publish(self):
self.date_published = timezone.now()
self.status = 'published'
self.save()
def save(self, *args, **kwargs):
# Set slug only on new posts
if not self.id:
self.slug = slugify(self.title)
self.last_modified = timezone.now()
super().save(*args, **kwargs)
def __str__(self):
return self.title
Hier ist die Ansicht (man kann sehen, dass ich das Beharren auf veröffentlichten Beiträge nur immer):
def post_view(request, slug):
post = get_object_or_404(Post, slug=slug, status='published')
return render(request, 'blog/single_post.html', {'post': post})
Hier ist die URL Eintritt:
url(r'^blog/(?P<slug>[-\w]+)/$', blog_view.post_view, name='single_post'),
Und schließlich, hier ist der Test:
class TestBlogViews(TestCase):
"""Class to test the views of our blog app"""
def setUp(self):
"""Make sure we have an environment in which to render the templates"""
# An author
self.author = Author()
self.author.name = 'Ankush'
self.author.short_name = 'ank'
self.author.save()
# A category
self.cat = Category()
self.cat.name = 'Programming'
self.cat.save()
# A post
self.post = Post()
self.post.title = 'Dummy title'
self.post.text = 'Dummy text that does nuffin'
self.post.author = self.author
self.post.category = self.cat
setup_test_environment()
self.client = Client()
def test_unpublished_post_raises_404(self):
self.post.save()
response = self.client.get(reverse('single_post', args=('dummy-title',)))
self.assertEqual(response.status_code, 404)
Also im Grunde versagt mein Test, weil ich 200 != 404
bekommen. Ich lief auch die Post
API von Shell, und bekam eine DoesNotExist
bei der Suche nach status = 'published'
auf einen Beitrag, der nur die save()
-Methode genannt hatte. Ich habe auch die response.content
in meinem Test gedruckt, und es enthält den benutzerdefinierten 404 Vorlageninhalt. Warum wirft es nicht 404, wenn das Objekt eindeutig nicht existiert? Irgendetwas stimmt nicht mit get_object_or_404()
?
P.S. Bitte lassen Sie mich wissen, wenn Sie weitere Codeschnipsel benötigen.
Welche Testdatenbank verwenden Sie? Können Sie sicherstellen, dass die Datenbank in der Tat sauber ist, ohne vorherige Daten, die die Situation irgendwie durcheinander bringen? –
@ShangWang Nun, ich verlasse mich auf die Testdatenbank, die Django erstellt (usong MariaDB 10.1, übrigens). Zerstört und rekonstruiert Django nicht jedes Mal Dinge? – dotslash
@ShangWang Okay, ich konnte etwas verbessern. Ich musste eigentlich einen neuen 'Client()' für jede Methode erstellen. Auf diese Weise erhalte ich jetzt den benutzerdefinierten Inhalt der 404-Seite, aber der Antwortcode ist immer noch "200". Komisch! : - | – dotslash