Django测试客户端发布请求无法重定向

时间:2019-08-15 11:58:08

标签: python django unit-testing

我发出请求时,我的django.test客户端返回的响应状态码为200,而不是重定向为状态码302。

我正在将Django 2.2.4与Python 3.7.3结合使用。

不需要登录(由Why does Django Redirect Test Fail?处理),也没有将follow和secure参数设置为True(由Django test client POST command not registering through 301 redirect处理)

我注意到相同的问题会影响我的更新视图。当我使用put方法调用Django Test Client时,它不会重定向。 (我没有包含此代码以避免冗长)。

最后,我注意到当我python manage.py runserver然后访问页面以创建新的Book实例时,页面重定向有效。

这是测试:

from django.test import TestCase, Client
from django.urls import reverse
...

class TestDashboardViews(TestCase):
    def setUp(self):
        self.client = Client()
        self.book_list_url = reverse("dashboard-home")
        self.book_create_url = reverse("dashboard-upload-book")
        self.another_demo_book_kwargs = {
            "title": "Demo Title",
            "author": "Demo Author",
            "subject": "Another Demo Subject",
            "details": "Another Demo Details",
            "file": "path/to/another/demo/file"
        }
        ...

    def test_book_create_view_using_post_method(self):
        response = self.client.post(self.book_create_url, self.another_demo_book_kwargs)

        self.assertRedirects(response, self.book_list_url)
        ...

这是受影响的视图:

class BookCreateView(CreateView):
    model = Book
    fields = ['title', 'author', 'subject', 'details', 'file']
    success_url = reverse_lazy("dashboard-home")

这是模型:

from django.db import models
from django.utils.text import slugify


class Book(models.Model):
    title = models.CharField(max_length=50)
    slug = models.SlugField()
    author = models.CharField(max_length=100)
    subject = models.CharField(max_length=50)
    details = models.CharField(max_length=255)

    def author_title_path(self, filename):
        return "files/{author}/{filename}".format(author=slugify(self.author), filename=filename)

    file = models.FileField(upload_to=author_title_path)

    def save(self, *args, **kwargs):
        title_by_author = "{title} by {author}".format(title=self.title, author=self.author)
        self.slug = slugify(title_by_author)
        super().save(*args, **kwargs)

这是我的网址:

from django.urls import path
from dashboard.views import BookListView, BookCreateView, BookUpdateView, BookDeleteView

urlpatterns = [
    path("", BookListView.as_view(), name="dashboard-home"),
    path("add_book/", BookCreateView.as_view(), name="dashboard-upload-book"),
    path("edit_book/<slug>/", BookUpdateView.as_view(), name="dashboard-edit-book"),
    path("delete_book/<slug>/", BookDeleteView.as_view(), name="dashboard-delete-book")
]

我的测试失败,并显示以下错误:

...
AssertionError: 200 != 302 : Response didn't redirect as expected: Response code was 200 (expected 302)
...

请帮助。

1 个答案:

答案 0 :(得分:0)

丹尼尔·罗斯曼(Daniel Roseman)和Dirkgroten帮助在评论中找出问题所在。

我建议检查出问题dirkgroten所指的是(how to unit test file upload in django

问题出在测试设置中创建的self.another_demo_book_kwargs中的文件字段中。

文件字段需要一个实际文件,而不仅仅是路径。

此:

self.another_demo_book_kwargs = {
            "title": "Demo Title",
            "author": "Demo Author",
            "subject": "Another Demo Subject",
            "details": "Another Demo Details",
            "file": "path/to/another/demo/file"
        }

应替换为:

with open(ABSOLUTE_FILE_PATH) as file_object:
            data = {
                "title": "Demo Title",
                "author": "Demo Author",
                "subject": "Another Demo Subject",
                "details": "Another Demo Details",
                "file": file_object
            }
            response = self.client.post(self.book_create_url, data)