Я пытаюсь высмеять прикованный вызов класса Djangos model.Manager()
. На данный момент я хочу высмеять методы values()
и filter()
.
Чтобы проверить, что я создал небольшой тестовый проект:
- Создание виртуальной среды
- Запустить
pip install django mock mock-django nose django-nose
- Создать проект
django-admin.py startproject mocktest
- Создать приложение
manage.py startapp mockme
- Добавьте
django_nose
иmocktest.mockme
вINSTALLED_APPS
(settings.py) - Добавьте
TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
в settings.py
Чтобы проверить, что все настроено правильно, я запустил manage.py test
. Выполняется одно испытание, стандартный тестовый Django создается при создании приложения.
Следующее, что я сделал, это создать очень простую модель.
mockme/models.py
from django.db import models
class MyModel(models.Model):
name = models.CharField(max_length=50)
Следующее, что я сделал, это создать простую функцию, которая использует MyModel
. Это функция, которую я хочу проверить позже.
mockme/functions.py
from models import MyModel
def chained_query():
return MyModel.objects.values('name').filter(name='Frank')
Здесь ничего особенного не происходит. Функция фильтрует объекты MyModel, чтобы найти все экземпляры, где name='Frank'
. Вызов значения() вернет ValuesQuerySet
, который будет содержать только поле имени всех найденных экземпляров MyModel.
mockme/tests.py
import mock
from django.test import TestCase
from mocktest.mockme.models import MyModel
from mocktest.mockme.functions import chained_query
from mock_django.query import QuerySetMock
class SimpleTest(TestCase):
def test_chained_query(self):
# without mocked queryset the result should be 0
result = chained_query()
self.assertEquals(result.count(), 0)
# now try to mock values().filter() and reeturn
# one 'Frank'.
qsm = QuerySetMock(MyModel, MyModel(name='Frank'))
with mock.patch('django.db.models.Manager.filter', qsm):
result = chained_query()
self.assertEquals(result.count(), 1)
Первый assertEquals будет оцениваться как успешный. Никакие экземпляры не возвращаются, так как диспетчер модели еще не издевается. Когда вызывается второй assertEquals, я ожидаю, что result
будет содержать экземпляр MyModel, который я добавил как возвращаемое значение в QuerySetMock:
qsm = QuerySetMock(MyModel, MyModel(name='Frank'))
Я высмеивал метод filter()
, а не метод values()
, так как я обнаружил, что это будет последний оцененный вызов, хотя я не уверен.
Тест завершится неудачно, потому что вторая переменная результата не будет содержать экземпляров MyModel.
Чтобы быть уверенным, что метод filter()
действительно издевался, я добавил инструкцию "отладочная печать":
from django.db import models
print models.Manager.filter
который возвратил:
<SharedMock name='mock.iterator' id='4514208912'>
Что я делаю неправильно?