2012-10-14 18 views
10

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:

  1. stworzenie środowiska wirtualnego
  2. Run pip install django mock mock-django nose django-nose
  3. Utwórz projekt django-admin.py startproject mocktest
  4. Utwórz aplikację manage.py startapp mockme
  5. Dodaj django_nose i mocktest.mockme to INSTALLED_APPS (settings.py)
  6. 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?

Odpowiedz

4

Spróbuj tego:

import mock 
from mocktest.mockme.models import MyModel 

class SimpleTest(TestCase): 
    def test_chained_query(self): 
     my_model_value_mock = mock.patch(MyModel.objects, 'value') 
     my_model_value_mock.return_value.filter.return_value.count.return_value = 10000 
     self.assertTrue(my_model_value_mock.return_value.filter.return_value.count.called) 
+0

Gdyby tak nie być ' 'wartości')'? – Splatmistro