Próbuję kpić z połączenia łańcuchowego na klasie Djangos model.Manager()
. Na razie chcę wyśmiać metodę values()
i filter()
.Django ORM - fałszywe wartości(). Filter() łańcuch
Aby przetestować że stworzyła mały projekt testowy:
- stworzenie środowiska wirtualnego
- Run
pip install django mock mock-django nose django-nose
- Utwórz projekt
django-admin.py startproject mocktest
- Utwórz aplikację
manage.py startapp mockme
- Dodaj
django_nose
imocktest.mockme
toINSTALLED_APPS
(settings.py) - Dodaj
TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
do settings.py
Aby verfiy, że wszystko jest ustawione poprawnie Pobiegłem manage.py test
. Jeden test jest uruchamiany, standardowy test, który tworzy Django podczas tworzenia aplikacji.
Następnie stworzyłem bardzo prosty model.
mockme/models.py
from django.db import models
class MyModel(models.Model):
name = models.CharField(max_length=50)
Następną rzeczą jaką zrobiłem było stworzyć prostą funkcję, która używa MyModel
. Tę funkcję chcę przetestować później.
mockme/functions.py
from models import MyModel
def chained_query():
return MyModel.objects.values('name').filter(name='Frank')
Nic specjalnego się dzieje tutaj. Funkcja filtruje obiekty MyModel, aby znaleźć wszystkie wystąpienia, w których name='Frank'
. Wywołanie wartości() zwróci wartość ValuesQuerySet
, która będzie zawierała tylko pole nazwy wszystkich znalezionych instancji 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)
Pierwsze assertEquals oceni jako udany. Żadne instancje nie są zwracane, ponieważ Menedżer modelu nie jest jeszcze kpiony. Po drugie assertEquals nazywa się spodziewać result
zawierać instancję MyModel I dodanej jako wartość zwracana do QuerySetMock:
qsm = QuerySetMock(MyModel, MyModel(name='Frank'))
I wyśmiewali metodę filter()
a nie metoda values()
odkąd okazało się, że będę ostatni oceniany zadzwoń, choć nie jestem pewien.
Test zakończy się niepowodzeniem, ponieważ druga zmienna wyników nie będzie zawierać żadnych instancji MyModel.
Aby mieć pewność, że metoda filter()
jest naprawdę szydzili dodałem "print debug" oświadczenie:
from django.db import models
print models.Manager.filter
który zwrócony:
<SharedMock name='mock.iterator' id='4514208912'>
Co robię źle?
Gdyby tak nie być ' 'wartości')'? – Splatmistro