Python 3.x 无法模拟数据库Django链查询

Python 3.x 无法模拟数据库Django链查询,python-3.x,django-models,mocking,python-unittest,Python 3.x,Django Models,Mocking,Python Unittest,我试图模拟django链查询。这些是 1. MyModel.objects.filter(userId=userId).exists() 2. mrvDb = MyModel.objects.filter(userId=userId).order_by('-dateViewed') 我试图模拟查询1。下面是我的方法 @mock.patch('myapp.models.MyModel.objects') @mock.patch('myapp.models.MyModel.obj

我试图模拟django链查询。这些是

 1. MyModel.objects.filter(userId=userId).exists()
 2. mrvDb = MyModel.objects.filter(userId=userId).order_by('-dateViewed')

我试图模拟查询1。下面是我的方法

   @mock.patch('myapp.models.MyModel.objects')
   @mock.patch('myapp.models.MyModel.objects')
   def test_retrieveMRVListService(self, param, most_Recently_Viewed_List):

      mock_MRVList_data = mock.MagicMock(spec=MyModel)
      mock_MRVList_data.userId = 6
      mock_MRVList_data.policyId = 6
      most_Recently_Viewed_List.filter.return_value = [mock_MRVList_data]  

    # param.filter.return_value = param
    param.filter.exists.return_value = "True"
为了这个。我收到错误:(AttributeError:'列表' 对象没有属性“存在”)

我正在尝试测试这个方法

def retrieveMRVListService(userId):
    if mostRecentlyViewedList.objects.filter(userId=userId).exists():
        mrvDb = mostRecentlyViewedList.objects.filter(
            userId=userId
            ).order_by('-dateViewed')[:5]
        mrvList = []
        for mrv in mrvDb:
            mrvData = {}
            mrvData["userId"] = mrv.userId
            mrvData["policyId"] = mrv.policyId
            mrvList.append(mrvData)
    else:
        mrvList = []
    return mrvList
我是unittest和模拟/测试django查询的新手。任何人都可以帮助解决链查询。任何帮助或引导,我都会非常感激。
如果需要任何信息,请告诉我。

您已经完成了大部分工作,这确实令人惊讶,因为大多数Python用户甚至不知道如何使用模拟。真正让你大吃一惊的是,
最近查看的列表.filter.return\u value实际上是一个
列表
,它正确地说它没有“exists”属性(因为它没有)

因此,请按步骤进行分解:

  • MyModel.objects.filter(userId=userId)返回一个
    QuerySet
    对象
  • 然后在步骤1返回的查询集上调用
    exists()
  • 因此,当你修补/模拟一个对象时,你必须正确地跟踪实际调用的对象以及调用的位置

    相反,您可以在步骤1中返回不同的模拟,然后修改该对象的返回调用,就像它是原始的
    QuerySet

    mock_queryset = Mock() # Create a mock of the QuerySet
    
    # in Django calling filter() returns a QuerySet, so lets do that
    
    most_Recently_Viewed_List.filter.return_value = mock_queryset
    
    # now modify the return value for the calls you make on that queryset
    mock_queryset.exists.return_value = True
    mock_queryset.order_by.return_value = [mock_MRVList_data] # just like your original code
    

    正如您所看到的,我们现在实际做的是模拟您在代码中调用的实际内容。

    Hey@William Bright如果我必须再次模拟查询MyModel.objects.filter(userId=userId),在我在上述问题中提到的查询1和2之后。如何用同样的方法再次模拟它。因为如果我像mock_queryset.filter.return_value=[mock_MRVList_data]一样模拟它。它不起作用。这里请更正。@Learner我会查找一些类似于“副作用”的内容,您可以提供一些您希望返回的内容