Проблема с созданием модульных тестов для действий администратора Django

У меня есть небольшие проблемы с тем, чтобы понять, где нужно насмехаться и ставить заплатки, и это не имеет смысла для меня. Я создаю действие администратора, которое получает токен из стороннего API, а затем создает экземпляр локального класса (который подключается к этому API) и выполняет вызовы API на основе id элемента.

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

Вот структура моего проекта.

from external_class_location import ReviewClass  # This is the class that hooks into the restaurant review location

from external_function_location import get_token  # This is the method that fetches the token from that external location

class UserAdmin(admin.ModelAdmin)
    actions = ['delete_reviews', ]

    def delete_reviews(self, request, queryset):
        reviews = ReviewClass(get_token())
        for user in queryset:
            reviews.delete_all_reviews(user)

    delete_reviews.short_description = "Delete all reviews for selected users"

У меня есть набор тестов, настроенный следующим образом

import unittest
from unittest.mock import Mock, patch

from django.contrib.auth.models import User
from django.urls import reverse
from django.test import TestCase

class UserAdminTestCase(TestCase):

    @patch('external_class_location.ReviewClass')
    @patch('requests.post')
    @patch('external_function_location.get_token')
    def test_delete_reviews(self, mock_token, mock_requests_post, reviews_mock):
        def setUp(self):
            self.username = 'test_user'
            self.password = 'test_password'
            self.user = User.objects.create_superuser(self.username, 'test@example.com', self.password)


        # the problem with this is that the requests.post method in the get_token method is being called even if I try to do this, which is why I had to create the MockRequest class below
        mock_token.return_value = 'blah' 

        # This method works in that it returns the 'blah' token from requests.post but ultimately requests.post should never actually be called because I'm trying to mock the get_token method entirely
        class MockRequest:
            def __init__(self, token):
                self.token = token

            def json(self):
                return dict(token=self.token)

        mock_requests_post.return_value = MockRequest('blah')

        sample_users = User.objects.all()[:10]
        change_url = reverse('admin:app_model_changelist')
        self.client.login(username=self.username, password=self.password)
        self.client.post(change_url, dict(action='delete_reviews', _selected_action=sample_users), follow=True)
        self.client.logout()

Я также застрял на последней части, где я просто хочу проверить, что метод delete_reviews был вызван 10 раз. Я пытаюсь высмеять весь класс, но это не работает (в классе есть метод, который проверяет токен при инстанцировании, и, устанавливая его равным 'blah', он выдает ошибку), и более того, я не уверен, как высмеять метод внутри высмеиваемого класса, чтобы затем проверить, что этот высмеиваемый метод был вызван 10 раз

Я занимаюсь этим уже несколько часов, поэтому любая помощь будет искренне признательна.

Вернуться на верх