2014-10-24 1 views
4

을 조롱 어떻게 CanonPerson 모델장고 모델 쿼리

def compute(self, is_send_emails, test_email_address): 
     cpses = CanonPerson.objects.filter(persons__vpd=6, 
              persons__country="United States", 
              persons__role__icontains=';IX;').prefetch_related("persons").using("global") 

     for cp in cpses: 
      ... 

나는 확실히 내가 계속할 수 있도록, 나에게 interable 모음을 반환 CanonPerson.objects.filter을 조롱하는 방법을 분실하고 다음 조롱하고 싶습니다.

이것은 내가 지금까지 무엇을했는지 있습니다 : 컴퓨팅 기능에

def test_X_count(self): 
    with mock.patch('apps.dbank.models.CanonPerson.objects.filter') as canon_patch: 
     mock_cp = mock.MagicMock(spec=CanonPerson) 
     mock_person = mock.MagicMock(spec=Person) 
     mock_person.vpd = 6 
     mock_cp.country = "United States" 
     mock_cp.role = ";IX;" 
     mock_cp.persons.add(mock_person) 
     canon_patch.objects.filter.return_value = [mock_cp] // ??? 
     oi = OptinInvites() 
     oi.compute(False, None) 
     oi.get_most_recent_email.assert_called_once_with(1) 

내가 cpses을 볼 수는 MagicMock 유형입니다. 그러나 iterable이 아니고 그 후에 for loop이 나오면 그냥 넘어갑니다. 반환 값을 [mock_cp]으로 설정하면 반복 가능한 목록을 만들 수 있다고 생각 했습니까?

+0

시도가 [mock_django] (https://github.com/dcramer/mock-django)를 사용합니다. 어쩌면 그것은 당신에게 도움이 될 것입니다. –

+0

테스트에서 실제 데이터를 생성하지 않는 이유는 무엇입니까? 그것이 정상적인 방법입니다. 또는 [factory boy]와 같은 것을 사용하십시오 (http://factoryboy.readthedocs.org/en/latest/). –

+0

매우 빠른 단위 테스트를 작성하려는 경우 장고 모델을 조롱하고 싶은 한 가지 이유가 있습니다. 완전 통합 테스트를 작성하려면 모델을 조롱하지 않아도됩니다. 두 가지 접근 방식이 각각 있습니다. – aychedee

답변

4

반환 값을 canon_patch으로 지정하는 행은 약간 잘못되었습니다. 당신은 여기서

canon_patch.objects.filter.return_value = [mock_cp] 

그것은해야한다 :

canon_patch.return_value = [mock_cp] 

canon_patch 이미 'objects.filter'의 모형입니다.

CanonPerson.objects.filter.objects.filter()으로 전화하면 원래 회선은 [mock_cp]입니다.

당신은 실제로 다음 CanonPerson 모델을 패치 할 경우 패치 라인과 같이 보일 것이다 : 오히려 당신은 또한 당신이 사용하고있는 위치에 조롱 필요하다는 사실을 발견

with mock.patch('apps.dbank.models.CanonPerson') as canon_patch: 

을, 당신이 그것을 가져 오는 위치보다. 그래서라는 모듈에서 CanonPerson를 사용하는 가정 my_module 시험에 패치 코드는 다음과 같습니다

with mock.patch('my_module.CanonPerson') as canon_patch: 
+0

당신이 말하는 것은 완벽하게 이해가됩니다. 그러나 mock.patch ('apps.dbank.models.CanonPerson')를 canon_patch로 변경했습니다 : 그러나 cpses = CanonPerson.objects.filter (mock 객체 대신 실제 모델을 가리키고 있습니다.) 왜 패치가 실패 했나요? 모델 응용 프로그램을 폭넓게 조롱해도 되겠습니까? – Houman

+0

모듈을 가져오고있는 모듈 대신 조심하십시오. 'your.module.CanonUser'. – aychedee

+0

잘 모르겠습니다. 당신은'canon_patch' 모의 객체를 생성하여'oi.compute (False, None) '에 전달해야한다는 것을 의미합니까? 그렇다면 모의 객체를 삽입 할 수 있도록 실제 코드를 변경해야한다는 것을 의미합니다. – Houman