Модульное тестирование Django: assertEqual Не сравнивает разрешение с 403 и завершается преждевременно внутри get_object()

#django #unit-testing #view #django-testing #django-tests

Вопрос:

Я действительно надеюсь, что вы можете пролить свет на загадочную ситуацию, в которой я нахожусь с моим модульным тестированием моих представлений сообщений. Я в основном пытаюсь протестировать различные разрешения на публикацию в зависимости от пользователя, например:

  1. гость (анонимный),
  2. участник (зарегистрированный), и
  3. участники, которые взаимно следят друг за другом (друзья)

Когда я запускаю модульный тест, в функции появляется ошибка, которая проверяет, может ли участник (зарегистрированный пользователь) просматривать сообщение, которое должно быть видно только друзьям (взаимно следующим друг за другом).:

 ======================================================================
ERROR: test_member_user_post_detail_friends_permission (journal.tests.test_views.TestPostDetailView)
----------------------------------------------------------------------

 

Когда я следую за строкой, в которой произошло исключение, это приводит меня к моему get_object() PostDetailView классу, где тестирование, похоже, заканчивается преждевременно (строка отмечена ниже).:

     def get_object(self, queryset=None):
        obj = super(PostDetailView, self).get_object(queryset=queryset)

        # Logged in user's friends ids (Users who they are following)
        my_friends = Follower.objects.filter(user_id=self.request.user.id).values(
            "follow_to"
        )

        # Post owner's friends id (Users who the post owner is following)
        their_friends = Follower.objects.filter(user_id=obj.user.id).values("follow_to")

        if obj.permission == "friend":  # viewable only by friends or staff/moderators

            if self.request.user.is_authenticated:
                if self.request.user.is_staff or self.request.user.is_moderator:
                    return obj

                if self.request.user.id == obj.user.id:
                    return obj

                # Check if they are following each other
                if self.request.user.id in [
                    i["follow_to"] for i in their_friends
                ] and obj.user.id in [i["follow_to"] for i in my_friends]:
                    return obj
                else:
                    raise PermissionDenied <-------------------------------------------------Issue here

        if self.request.user.is_anonymous and obj.permission != "public":
            raise PermissionDenied
        return obj
 

Ожидание:

self.assertEqual(response.status_code, 403) должен быть истинным, 403 == 403

Вопрос:

  1. Теперь я не понимаю, почему мое self.assertEqual(response.status_code, 403) утверждение не возвращает True, потому что не должно поднимать PermissionDenied == 403 ?
  2. Почему он преждевременно завершается еще до того, как мой модульный тест сможет запустить строку self.assertEqual?
  3. Как я могу изменить свой код, чтобы мой модульный тест работал успешно?

Правка: Глупый я, кажется, забыл вставить фактический тест:

     def test_member_user_post_detail_friends_permission(self):
        """
        Test if logged in user can view friend permission posts
        """
        request = self.factory.get("/journal/post/3/")
        middleware = SessionMiddleware()
        middleware.process_request(request)
        request.session.save()
        request.user = self.user_1
        response = PostDetailView.as_view()(request, pk=self.friends_post.id)
        self.assertEqual(response.status_code, 403)
 

Edit2: Это работает, если я использую client (), но не если я использую factory(). Что это дает?

         self.client.login(username="user_1", password="123456")
        response = self.client.get('/journal/post/3/')
        self.assertEqual(response.status_code, 403)
 

Комментарии:

1. PostDetailView.as_view()(request, pk=self.friends_post.id) вы напрямую передаете запрос в представление, чего вы ожидаете? Обычно существует некоторый код, который Django должен перехватывать эти исключения, а затем возвращать соответствующий ответ вместо того, чтобы вы пытались напрямую использовать представление.