Тест Django завершается неудачей со словами "Ни один пользователь не соответствует заданному запросу".
Я написал приложение Django и теперь пытаюсь покрыть его автоматизированными тестами. Для тестирования функции get_queryset
внутри моего ListView
я создал тестового пользователя и его пост, но мой тест терпит неудачу с "No User matches the given query
". Когда я выполняю py manage.py runserver
, все в порядке, никаких исключений не возникает, и страница отображается правильно. Я новичок в тестировании Django, поэтому совершенно не понимаю, что происходит. Не могли бы вы мне помочь?
Вот мой вид из view.py
class UserPostListView(ListView):
"""Displaying a page with a certain user's posts"""
model = Post
template_name = 'blog/user_posts.html'
context_object_name = 'posts'
paginate_by = 5
def get_queryset(self):
"""Dynamic filtering to get posts by a chosen user"""
queryset = super().get_queryset()
user = get_object_or_404(User, username=self.kwargs.get('username'))
return queryset.filter(author=user).order_by('-date_posted')
Тест для этого представления:
class TestUserPostListView(TestCase):
"""Test UserPostListView"""
def setUp(self):
"""Creating a test user and his post to see if the certain
user's page with posts is displayed properly"""
self.factory = RequestFactory()
self.user = User.objects.create_user(
username='test_user',
email='testuser@example.com',
password='fhhewo87539275'
)
self.post = Post.objects.create(
title='test_post',
content='blabla',
author=self.user
)
def test_get_queryset(self):
"""Testing get_queryset function"""
url = reverse('user-posts', kwargs={'username': self.user.username})
request = self.factory.get(url)
view = UserPostListView()
view.setup(request)
queryset = view.get_queryset()
self.assertIn(self.post, queryset)
Traceback:
Traceback (most recent call last):
File "C:\Users\473491\Documents\django\web_blog\env\lib\site-packages\django\shortcuts.py", line 76, in get_object_or_404
return queryset.get(*args, **kwargs)
File "C:\Users\473491\Documents\django\web_blog\env\lib\site-packages\django\db\models\query.py", line 435, in get
raise self.model.DoesNotExist(django.contrib.auth.models.User.DoesNotExist: User matching query does not exist.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\473491\Documents\django\web_blog\web_blog\apps\blog\test\test_views.py", line 67, in test_get_queryset
queryset = view.get_queryset()
File "C:\Users\473491\Documents\django\web_blog\web_blog\apps\blog\views.py", line 45, in get_queryset
user = get_object_or_404(User, username=self.kwargs.get('username'))
File "C:\Users\473491\Documents\django\web_blog\env\lib\site-packages\django\shortcuts.py", line 78, in get_object_or_404
raise Http404('No %s matches the given query.' % queryset.model._meta.object_name)
django.http.response.Http404: Ни один пользователь не соответствует заданному запросу.
Я выяснил, в чем заключалась проблема. Мой UserPostListView
вызывается по url, содержащему url-переменную.
Мой urlpattern, соответствующий представлению:
path('users/<str:username>', UserPostListView.as_view(), name='user-posts')
Я также использую username
из url для фильтрации постов, созданных пользователем с таким именем, вызывая функцию get_queryset
в UserPostListView
.
Я внимательно прочитал документацию и обнаружил:
Когда представление вызывается во время цикла запрос/ответ, метод setup() присваивает HttpRequest атрибуту request представления, а любые позиционные и/или ключевые аргументы, захваченные из шаблона URL, атрибутам args и kwargs соответственно.
Это означает, что вместо view.setup(request)
я должен был написать view.setup(request, username=self.user.username)
Когда я исправил это, тест стал выполняться правильно и не давал сбоев.