【问题标题】:Not able to mock the database Django chain queries无法模拟数据库 Django 链查询
【发布时间】:2019-05-01 19:52:59
【问题描述】:

我正在尝试模拟 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:'list' 对象没有“存在”属性)

我正在尝试测试这个方法。

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 和 mock/test django 查询的新手。任何人都可以帮助解决链查询。任何帮助或领导,我将不胜感激。 如果需要任何信息,请告诉我。

【问题讨论】:

    标签: python-3.x django-models mocking python-unittest


    【解决方案1】:

    您已经完成了大部分工作,这实际上是惊人的,因为大多数 Python 人甚至不知道如何使用 Mock。实际上让你感到困惑的是most_Recently_Viewed_List.filter.return_value实际上是List,它正确地说它没有“exists”属性(因为它没有)。

    所以按步骤分解:

    1. MyModel.objects.filter(userId=userId) 返回一个QuerySet 对象。
    2. 然后在第 1 步返回的 QuerySet 上调用 exists()。

    因此,当您修补/模拟对象时,您必须正确跟踪实际调用的内容和位置。

    您可以做的是在第 1 步中返回一个不同的 Mock,然后修改该对象的返回调用,就好像它是原来的 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
    

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

    【讨论】:

    • 嘿@William Bright,如果我必须再次模拟查询 MyModel.objects.filter(userId=userId) 在我在以上问题。如何以相同的方法再次模拟它。因为如果我像 mock_queryset.filter.return_value = [mock_MRVList_data] 那样嘲笑它。它不工作。在这里纠正我。
    • @Learner 我会查找类似“副作用”的东西,您基本上可以提供一些您希望返回的东西
    猜你喜欢
    • 2020-01-22
    • 2014-02-25
    • 2016-11-21
    • 2016-08-03
    • 2012-12-22
    • 2018-03-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多