2016-05-27 13 views
2

ビューの応答をテストするために書いたDjangoテストで期待される動作が得られないという奇妙なエラーに直面しています。テストクライアントが404エラーをスローしない

は、シンプルなブログアプリケーションのための次のモデルを考えてみましょう:

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 

ここでビューが(私が唯一公表ポストを得ることを主張していていることがわかります)です。

def post_view(request, slug): 
    post = get_object_or_404(Post, slug=slug, status='published') 
    return render(request, 'blog/single_post.html', {'post': post}) 

ここにURLがありますエントリ:

url(r'^blog/(?P<slug>[-\w]+)/$', blog_view.post_view, name='single_post'), 

最後に、次のテストがあります。

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) 

基本的に、私は200 != 404を取得しているので、私のテストは失敗します。私もシェルからPost apiを実行し、save()メソッドしか呼び出されていない投稿でstatus = 'published'を探すときにDoesNotExistを得ました。私はresponse.contentを私のテストで印刷し、カスタム404テンプレートの内容を含んでいます。オブジェクトが明確に存在しないときに404を投げないのはなぜですか? get_object_or_404()に問題がありますか?

P.S.コードのスニペットが必要な場合はお知らせください。

+0

どのテストデータベースを使用していますか?以前のデータがなくてもデータベースが本当にきれいであることを確認して、何らかの形で状況を混乱させることはできますか? –

+0

@ShangWangまあ、私はDjangoが作成したテストデータベース(ちなみに、MarongDB 10.1を使用しています)に頼っています。 Djangoは毎回物事を破壊したり再構築したりしませんか? – dotslash

+0

@ ShangWang私はいくつかの改善を行うことができました。私は実際にすべてのメソッドに対して新しい 'Client()'を作成しなければなりませんでした。このようにして、カスタム404ページのコンテンツを取得しましたが、レスポンスコードはまだ「200」です。面白い! : - | – dotslash

答えて

1

いいえ、私はそれを理解することができました。私のカスタム404ビューをめちゃくちゃにして判明:

それがあった:

def not_found(request): 
    return render(request, 'ankblog/not_found.html') 

だから、自然にステータスコードが200ました。それはreturn render(request, 'ankblog/not_found.html', status=404)に変更することで修正されました。

私は面白いと思います。私はカスタム404が自動的に404エラーを起こしたと思っていたでしょう。

関連する問題