Ich versuche, einen verketteten Anruf auf der Djangos model.Manager()
Klasse zu verspotten. Für jetzt möchte ich die Methode values()
und filter()
verspotten.Django ORM - Mock Werte(). Filter() Kette
Um zu testen, dass ich ein kleines Testprojekt erstellt:
- eine virtuelle Umgebung
- Run erstellen
pip install django mock mock-django nose django-nose
- Erstellen Sie ein Projekt
django-admin.py startproject mocktest
- eine App
manage.py startapp mockme
- hinzufügen erstellen
django_nose
undmocktest.mockme
zuINSTALLED_APPS
(settings.py) TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
hinzufügen
settings.py ist, dass alles verfiy Setup richtig lief ich manage.py test
. Ein Test wird ausgeführt, der Standardtest, den Django erstellt, wenn Sie eine App erstellen.
Als nächstes habe ich ein sehr einfaches Modell erstellt.
mockme/models.py
from django.db import models
class MyModel(models.Model):
name = models.CharField(max_length=50)
Das nächste, was ich tat, war eine einfache Funktion zu erstellen, die MyModel
verwendet. Das ist die Funktion, die ich später testen möchte.
mockme/functions.py
from models import MyModel
def chained_query():
return MyModel.objects.values('name').filter(name='Frank')
Nichts Besonderes geschieht hier. Die Funktion filtert die MyModel-Objekte, um alle Instanzen zu finden, in denen name='Frank'
. Der Aufruf von values () gibt eine ValuesQuerySet
zurück, die nur das Namensfeld aller gefundenen MyModel-Instanzen enthält.
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)
Die erste assertEquals wird als erfolgreich bewerten. Es werden keine Instanzen zurückgegeben, da der Modellmanager noch nicht verspottet wurde. Wenn die zweite assertEquals I erwarten result
genannt MyModel Instanz I enthalten als Rückgabewert auf den QuerySetMock hinzugefügt:
qsm = QuerySetMock(MyModel, MyModel(name='Frank'))
ich die filter()
Methode verspottet und nicht die values()
Methode, da fand ich wird es die letzte ausgewertet werden ruf an, obwohl ich mir nicht sicher bin.
Der Test schlägt fehl, weil die zweite Ergebnisvariable keine MyModel-Instanzen enthält.
Um sicher zu sein, dass die filter()
Methode wirklich eine "Debug-print" Aussage, die ich verspottet wird hinzugefügt:
from django.db import models
print models.Manager.filter
die zurückgegeben:
<SharedMock name='mock.iterator' id='4514208912'>
Was mache ich falsch?
Sollte das nicht sein ' 'Werte')'? – Splatmistro