Метод assertJSONEqual

Метод assertJSONEqual применяется к объекту тестового класса TestCase и выполняет сравнение двух JSON-строк на эквивалентность. Этот метод полезен при тестировании API-эндпоинтов, возвращающих JSON-ответы. Он проверяет, что JSON-структуры совпадают по ключам и значениям, игнорируя различия в форматировании и порядке следования ключей. В случае несовпадения метод генерирует исключение с подробным сообщением об ошибке.

Метод принимает три обязательных аргумента: строку с ожидаемым JSON-значением, строку с фактическим JSON-значением и опциональное сообщение об ошибке. Сравнение выполняется после десериализации строк в Python-объекты, что позволяет корректно сравнивать вложенные структуры и массивы.

Синтаксис

pythonself.assertJSONEqual(raw, expected, msg=None)

Параметры

⁅b⁆raw⁅/b⁆ - строка с фактическим JSON-ответом, который нужно проверить.

⁅b⁆expected⁅/b⁆ - строка с ожидаемым JSON-значением для сравнения.

⁅b⁆msg⁅/b⁆ - необязательное сообщение об ошибке, которое будет выведено в случае неудачного сравнения.

Пример . С API-эндпоинтом

Проверим JSON-ответ от API, возвращающего данные о статье:

pythonfrom django.test import TestCase
from django.urls import reverse
from myapp.models import Article

class ArticleAPITestCase(TestCase):
  def test_article_api_response(self):
    # Создаем тестовую статью
    article = Article.objects.create(
      title="Test Article",
      status="published",
      content="Test content"
    )

    # Получаем ответ от API
    url = reverse('article-detail', args=[article.id])
    response = self.client.get(url)

    # Ожидаемый JSON-ответ
    expected_json = '{"id": 1, "title": "Test Article", "status": "published"}'

    # Сравниваем JSON-строки
    self.assertJSONEqual(response.content, expected_json)

Пример . С вложенной структурой

Проверим JSON-ответ с вложенными объектами и массивами:

pythonfrom django.test import TestCase
from django.urls import reverse
from myapp.models import Article, Category

class ArticleListAPITestCase(TestCase):
  def test_articles_list_response(self):
    # Создаем категорию
    category = Category.objects.create(name="Technology")

    # Создаем несколько статей
    Article.objects.create(
      title="Python Guide",
      status="published",
      category=category
    )
    Article.objects.create(
      title="Django Tips",
      status="draft",
      category=category
    )

    # Получаем ответ от API
    url = reverse('article-list')
    response = self.client.get(url)

    # Ожидаемый JSON с массивом
    expected_json = '''
    {
      "data": [
        {"id": 1, "title": "Python Guide", "category": "Technology"},
        {"id": 2, "title": "Django Tips", "category": "Technology"}
      ],
      "count": 2
    }
    '''

    self.assertJSONEqual(response.content, expected_json)

Пример . С форматированными JSON-строками

Покажем, что метод игнорирует различия в форматировании:

pythonfrom django.test import TestCase
from django.urls import reverse
from myapp.models import User

class UserAPITestCase(TestCase):
  def test_user_api_with_formatting(self):
    # Создаем пользователя
    user = User.objects.create(
      username="john_doe",
      email="john@example.com",
      is_active=True
    )

    # Получаем ответ от API
    url = reverse('user-detail', args=[user.id])
    response = self.client.get(url)

    # Ожидаемый JSON с произвольным форматированием
    expected_json = '{"id":1,"is_active":true,"username":"john_doe","email":"john@example.com"}'

    # Фактический ответ может содержать пробелы и переносы
    # assertJSONEqual успешно сравнит эти строки
    self.assertJSONEqual(response.content, expected_json)

Пример . С сообщением об ошибке

Используем опциональное сообщение для отладки:

pythonfrom django.test import TestCase
from django.urls import reverse
from myapp.models import Product

class ProductAPITestCase(TestCase):
  def test_product_api_with_custom_message(self):
    # Создаем товар
    product = Product.objects.create(
      name="Laptop",
      price=999.99,
      in_stock=True
    )

    # Получаем ответ от API
    url = reverse('product-detail', args=[product.id])
    response = self.client.get(url)

    # Ожидаемый JSON
    expected_json = '{"id": 1, "name": "Laptop", "price": 999.99}'

    # Добавляем сообщение об ошибке для отладки
    self.assertJSONEqual(
      response.content,
      expected_json,
      msg="Product API response doesn't match expected structure"
    )

Результат выполнения кода при ошибке:

python"AssertionError: Product API response doesn't match expected structure"

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

  • метод assertContains,
    который проверяет наличие подстроки в HTTP-ответе
  • метод assertRedirects,
    который проверяет HTTP-редирект в ответе
  • метод assertTemplateUsed,
    который проверяет использованный HTML-шаблон в ответе
  • метод assertNumQueries,
    который проверяет количество выполненных SQL-запросов