2016-12-06 3 views
0

Hier ist eine kleine Klasse (in myapp/getters.py):Wie kann ich eine Methode eines Django Model Managers verspotten?

from django.contrib.auth.models import User 

class UserGetter: 
    def get_user(self): 
     return User.objects.get(username='username') 

Ich mag den Anruf zu User.objects.get verspotten, gibt ein MagicMock und Test, dass die Methode gibt, was injizierte ich. In myapp/tests/tests_getters.py:

from unittest import TestCase 
from django.contrib.auth.models import User, UserManager 
from mock import patch, create_autospec 
from myapp.getters import UserGetter 

class MockTestCase(TestCase): 
    @patch('myapp.getters.User', autospec=True) 
    def test(self, user_class): 
     user = create_autospec(User) 
     objects = create_autospec(UserManager) 
     objects.get.return_value = user 
     user_class.objects.return_value = objects 
     self.assertEquals(user, UserGetter().get_user()) 

Aber wenn ich diesen Test laufen (mit python manage.py test myapp.tests.tests_getters) bekomme ich

AssertionError: 
    <MagicMock name='User.objects().get()' spec='User' id='4354507472'> != 
    <MagicMock name='User.objects.get()' id='4360679248'> 

Warum kann ich nicht das Mock zurück ich injiziert? Wie kann ich diesen Test richtig schreiben?

Antwort

1

Ich denke, das ist Ihr Problem:

user_class.objects.return_value = objects 

Sie die Mock anweisen, eine Funktion „Objekte“ zu haben, der die Objekte auf der rechten Seite zurückgibt.
Aber Ihr Code ruft niemals eine objects() - Funktion auf. Es greift auf die User.objects-Eigenschaft zu, Benutzer ist ein Mock hier, also gibt Benutzer einen neuen Mock beim Zugriff auf Eigenschaften zurück.

+0

Das ist es. Die Lösung besteht darin, 'user_class.objects.return_value = objects' in' user_class.objects = objects' zu ändern. Es funktioniert auch, wenn ich "User" nicht patch und nur "User.objects" zuweisen, aber ich vermute, das würde andere Tests kontaminieren. –

Verwandte Themen