作为简化示例,我为UpdateView
模型编写了Book
,并在成功时为ListView
重定向:
from django.urls import reverse
from django.views.generic import ListView
from django.views.generic.edit import UpdateView
from .models import Book
class BookUpdate(UpdateView):
model = Book
fields = ['title', 'author']
class BookList(ListView):
model = Book
Book
模型定义为
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=100, blank=True)
def get_absolute_url(self):
return reverse('books-list')
其中urls.py
是
from django.urls import path
from books.views import BookUpdate, BookList
urlpatterns = [
path('books/', BookList.as_view(), name='books-list'),
path('book/<int:pk>/', BookUpdate.as_view(), name='book-update')
]
在books/tests.py
中,我试图编写以下测试:
class BookUpdateTest(TestCase):
def test_update_book(self):
book = Book.objects.create(title='The Catcher in the Rye')
response = self.client.post(
reverse('book-update', kwargs={'pk': book.id}),
{'author': 'J.D. Salinger'})
self.assertEqual(response.status_code, 200)
book.refresh_from_db()
self.assertEqual(book.author, 'J.D. Salinger')
但是,此测试失败是因为book
author
在POST
请求后似乎没有更新,即使在从数据库刷新后也是如此:
FAIL: test_update_book (books.tests.BookUpdateTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/kurtpeek/Documents/Scratch/book_project/books/tests.py", line 46, in test_update_book
self.assertEqual(book.author, 'J.D. Salinger')
AssertionError: '' != 'J.D. Salinger'
+ J.D. Salinger
另一方面,如果我运行开发服务器并手动填写字段,一切似乎都按预期工作。如何为UpdateView
编写一个单元测试,用于捕获用户更新字段,提交表单以及更改相应的对象?
答案 0 :(得分:7)
如果您POST
表单,您必须发布所有必填字段,而不仅仅是您要更新的字段 - 即使基础模型的必填字段已经有值。此外,成功更新后返回的状态代码为302'Find',而不是200'Oct'。因此,以下测试通过:
class BookUpdateTest(TestCase):
def test_update_book(self):
book = Book.objects.create(title='The Catcher in the Rye')
response = self.client.post(
reverse('book-update', kwargs={'pk': book.id}),
{'title': 'The Catcher in the Rye', 'author': 'J.D. Salinger'})
self.assertEqual(response.status_code, 302)
book.refresh_from_db()
self.assertEqual(book.author, 'J.D. Salinger')
答案 1 :(得分:0)
在 Django 3.2 中,您可以在这里找到规范的解决方案: https://docs.djangoproject.com/fr/3.2/ref/urlresolvers/
在测试中,您只需要:
self.topic = Book.objects.create(slug="test-update")
self.response = self.client.get(reverse('book_update', args=[self.topic.slug]))