Класс AsyncRequestFactory

Класс AsyncRequestFactory предназначен для создания асинхронных HTTP-запросов в тестовой среде Django. Он позволяет имитировать GET, POST, PUT, DELETE и другие типы запросов, возвращая объект запроса, который можно напрямую передать асинхронному представлению. Основное отличие от синхронного RequestFactory заключается в поддержке асинхронных операций и работе с ASGIRequest объектами.

Синтаксис

pythonfrom django.test import AsyncRequestFactory

factory = AsyncRequestFactory()
request = factory.get(path, data, content_type, **extra)
request = factory.post(path, data, content_type, **extra)
request = factory.put(path, data, content_type, **extra)
request = factory.delete(path, data, content_type, **extra)
request = factory.patch(path, data, content_type, **extra)
request = factory.head(path, data, content_type, **extra)
request = factory.options(path, data, content_type, **extra)

После создания запроса его можно передать асинхронному представлению, которое должно быть вызвано с ключевым словом await. Полученный ответ можно проверять с помощью стандартных утверждений Django TestCase.

Пример . Создание GET запроса

Рассмотрим базовый пример создания асинхронного GET запроса к представлению, которое возвращает список статей:

pythonfrom django.test import AsyncRequestFactory, TestCase
from myapp.views import article_list

class ArticleViewTests(TestCase):
  async def test_get_articles(self):
    factory = AsyncRequestFactory()
    request = factory.get('/api/articles/')
    
    response = await article_list(request)
    
    self.assertEqual(response.status_code, 200)
    self.assertContains(response, 'article')

Пример . Создание POST запроса с данными

Создадим POST запрос для добавления новой статьи, передавая данные в формате JSON:

pythonfrom django.test import AsyncRequestFactory, TestCase
from myapp.views import create_article
import json

class ArticleCreateTests(TestCase):
  async def test_post_article(self):
    factory = AsyncRequestFactory()
    data = {
      'title': 'New Article',
      'content': 'Content of new article',
      'status': 'draft'
    }
    
    request = factory.post(
      '/api/articles/',
      data=json.dumps(data),
      content_type='application/json'
    )
    
    response = await create_article(request)
    
    self.assertEqual(response.status_code, 201)
    self.assertContains(response, 'New Article')

Пример . Создание запроса с дополнительными заголовками

Передадим дополнительные HTTP-заголовки для авторизации и указания предпочтительного формата ответа:

pythonfrom django.test import AsyncRequestFactory, TestCase
from myapp.views import user_profile

class UserProfileTests(TestCase):
  async def test_profile_with_auth(self):
    factory = AsyncRequestFactory()
    
    request = factory.get(
      '/api/profile/',
      HTTP_AUTHORIZATION='Bearer token123',
      HTTP_ACCEPT='application/json'
    )
    
    response = await user_profile(request)
    
    self.assertEqual(response.status_code, 200)
    self.assertEqual(response['Content-Type'], 'application/json')

Пример . Работа с асинхронным middleware

AsyncRequestFactory позволяет тестировать асинхронные middleware, передавая запрос через цепочку обработчиков:

pythonfrom django.test import AsyncRequestFactory, TestCase
from django.core.handlers.asgi import ASGIHandler
from myapp.middleware import async_logger_middleware
from myapp.views import home_view

class MiddlewareTests(TestCase):
  async def test_async_middleware(self):
    factory = AsyncRequestFactory()
    request = factory.get('/home/')
    
    response = await async_logger_middleware(home_view)(request)
    
    self.assertEqual(response.status_code, 200)
    self.assertTrue(hasattr(request, 'logger'))

Пример . Тестирование обработки ошибок

Протестируем, как представление обрабатывает ошибки при некорректных данных запроса:

pythonfrom django.test import AsyncRequestFactory, TestCase
from myapp.views import update_article

class ArticleUpdateTests(TestCase):
  async def test_update_with_invalid_data(self):
    factory = AsyncRequestFactory()
    invalid_data = {'status': 'invalid_status'}
    
    request = factory.patch(
      '/api/articles/1/',
      data=invalid_data,
      content_type='application/json'
    )
    
    response = await update_article(request, pk=1)
    
    self.assertEqual(response.status_code, 400)
    self.assertContains(response, 'Invalid status')

Смотрите также

  • класс AsyncClient,
    который предоставляет клиент для асинхронных запросов
  • класс RequestFactory,
    который создаёт синхронные тестовые запросы
  • класс Client,
    который эмулирует полноценный браузер для тестирования
  • класс TestCase,
    который предоставляет базовый класс для тестов