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?
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. –