如何模拟Django模型管理器的方法?
问题描述:
这里是一个小类(在myapp/getters.py
):如何模拟Django模型管理器的方法?
from django.contrib.auth.models import User
class UserGetter:
def get_user(self):
return User.objects.get(username='username')
我想调用模拟出到User.objects.get
,返回MagicMock
,并测试该方法返回我注射。在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())
但是当我运行这个测试(与python manage.py test myapp.tests.tests_getters
)我得到
AssertionError:
<MagicMock name='User.objects().get()' spec='User' id='4354507472'> !=
<MagicMock name='User.objects.get()' id='4360679248'>
为什么我不回来我注射模拟?我该如何正确编写这个测试?
答
我觉得这是你的问题:
user_class.objects.return_value = objects
您指示模拟有功能的“对象”,返回右侧的对象。
但是你的代码永远不会调用任何对象()函数。它访问User.objects属性,用户在这里是一个模拟,所以用户返回一个新的模拟属性访问。
就是这样。解决方法是将'user_class.objects.return_value = objects'更改为'user_class.objects = objects'。如果我不修补'User'并将其分配给'User.objects',它也可以工作,但是我怀疑这会污染其他测试。 –