我试图在Djangosmodel.Manager()
类上模拟一个链式调用。现在我想模拟values()
和filter()
方法。
为了测试我创建了一个小测试项目:
pip install django mock mock-django nose django-nose
django-admin.py startproject mocktest
manage.py startapp mockme
django_nose
和mocktest.mockme
添加到INSTALLED_APPS
(settings.py)TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
添加到settings.py为了确认一切设置正确,我运行了manage.py test
。一个测试是运行的,即Django在创建应用程序时创建的标准测试。
接下来我做的是创建一个非常简单的模型。
模拟/模型.py
from django.db import models
class MyModel(models.Model):
name = models.CharField(max_length=50)
接下来我要做的是创建一个使用MyModel
的简单函数。这就是我稍后要测试的函数。
mockme/functions.py
from models import MyModel
def chained_query():
return MyModel.objects.values('name').filter(name='Frank')
这里没有什么特别的事发生。函数正在筛选MyModel对象,以查找name='Frank'
中的所有实例。对values()的调用将返回一个ValuesQuerySet
,它将只包含找到的所有MyModel实例的name字段。
模拟/测试.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)
第一批资产评估合格。由于尚未模拟模型管理器,因此不返回任何实例。当调用第二个assertEquals时,我希望result
包含我作为返回值添加到QuerySetMock的MyModel实例:
qsm = QuerySetMock(MyModel, MyModel(name='Frank'))
我嘲笑了filter()
方法,而不是values()
方法,因为我发现它将是最后一个被求值的调用,尽管我不确定。
测试将失败,因为第二个结果变量将不包含任何MyModel实例。
为了确保filter()
方法被真正模拟,我添加了一个“debug print”语句:
from django.db import models
print models.Manager.filter
结果是:
<SharedMock name='mock.iterator' id='4514208912'>
我做错什么了?
@Gin的答案在很大程度上帮助了我,但在我的例子中,我正在修补
MyModel.objects
,而我正在嘲笑的查询如下所示:MyModel.objects.filter(arg1=user, arg2=something_else).order_by('-something').first()
所以这对我有效:
此外,修补属性的顺序很重要,并且必须与您在测试函数中调用它们的顺序匹配。
试试这个:
相关问题 更多 >
编程相关推荐