Вымывание Django Queryset для проверки функции, которая принимает запрос

У меня есть функция утилиты в моем проекте Django, она принимает запрос, получает некоторые данные из него и возвращает результат. Я хотел бы написать несколько тестов для этой функции. Нужно ли вообще «издеваться» над QuerySet? Я хотел бы создать объект, который не касается базы данных, и я могу предоставить ему список используемых значений (т. Е. Некоторые поддельные строки), а затем он будет действовать точно так же, как набор запросов, и позволит кому-то делать полевые поиска на нем / filter / get / all и т. д.

Что-то вроде этого уже существует?

6 Solutions collect form web for “Вымывание Django Queryset для проверки функции, которая принимает запрос”

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

Конечно, вы можете издеваться над QuerySet, вы можете издеваться над чем угодно.

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

Низкотехнологичный способ начать работу – определить объект:

class MockQuerySet(object): pass 

затем создайте один из них и передайте его в свой тест. Тест завершится неудачно, вероятно, на AttributeError. Это скажет вам, что вам нужно реализовать на вашем MockQuerySet. Повторяйте, пока ваш объект не будет достаточно богат для ваших тестов.

У меня такая же проблема, и похоже, что какой-то хороший человек написал библиотеку для издевательств QuerySets, она называется mock-django, и конкретный код вам понадобится здесь https://github.com/dcramer/mock-django /blob/master/mock_django/query.py Я думаю, что вы можете просто исправить вашу функцию объектов объектов, чтобы вернуть один из этих объектов QuerySetMock, который вы настроили, чтобы вернуть что-то ожидаемое!

Для этого я использую функцию .none () Django .

Например:

 class Location(models.Model): name = models.CharField(max_length=100) mock_locations = Location.objects.none() 

Этот метод часто используется в собственных внутренних тестах Django. Основываясь на комментариях в коде

 Calling none() will create a queryset that never returns any objects and no +query will be executed when accessing the results. A qs.none() queryset +is an instance of ``EmptyQuerySet``. 

Для пустого Queryset я бы просто отказался от использования, поскольку keithhackbarth уже заявил .

Однако, чтобы издеваться над Queryset, который вернет список значений, я предпочитаю использовать Mock со spec диспетчера модели. В качестве примера (стиль Python 2.7 – я использовал внешнюю библиотеку Mock ), вот простой тест, где Queryset фильтруется, а затем подсчитывается:

 from django.test import TestCase from mock import Mock from .models import Example def queryset_func(queryset, filter_value): """ An example function to be tested """ return queryset.filter(stuff=filter_value).count() class TestQuerysetFunc(TestCase): def test_happy(self): """ `queryset_func` filters provided queryset and counts result """ m_queryset = Mock(spec=Example.objects) m_queryset.filter.return_value = m_queryset m_queryset.count.return_value = 97 result = func_to_test(m_queryset, '__TEST_VALUE__') self.assertEqual(result, 97) m_queryset.filter.assert_called_once_with(stuff='__TEST_VALUE__') m_queryset.count.assert_called_once_with() 

Однако, чтобы return_value вопрос, вместо того, чтобы устанавливать значение return_value для count , это можно легко настроить, чтобы быть list экземпляров модели, возвращаемых из all .

Обратите внимание, что привязка обрабатывается путем установки filter для возврата издеваемого набора запросов:

 m_queryset.filter.return_value = m_queryset 

Это необходимо применять для любых методов запроса, используемых в тестируемой функции, например, exclude и т. Д.

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

Для проблемы с базой данных я исследовал, использует ли django sqlite-in-memory, и я узнал, что в последней версии django используется база данных sqlite -in-memory, начиная с страницы django unittest :

При использовании ядра базы данных SQLite тесты по умолчанию будут использовать базу данных в памяти (т. Е. База данных будет создана в памяти, полностью обходя файловую систему!).

Издевательство над объектом QuerySet не заставит вас реализовать свою полную логику.

  • перейдите в интерактивный сеанс, чтобы проверить неудавшийся модульный тест
  • Python unitest - использовать переменные, определенные в настройках модуля и класса, в тестах
  • Создание и импорт вспомогательных функций в тестах без создания пакетов в тестовой директории с использованием py.test
  • Neo4j ImpermanentDatabase в python unittests
  • InvalidBasesError: не удается разрешить базы для
  • «Почти равный» в жасмине
  • Тестирование загрузки файлов с помощью Flask и Python 3
  • Утилиты Python продолжаются после отказа
  • Python - лучший язык программирования в мире.