在python中的函数中使用不同的返回值模拟相同的方法两次

时间:2016-02-17 20:53:23

标签: python python-2.7

我有一个使用pytest测试的方法。该方法两次调用相同的数据库模型。

 def function:
    ids = database_model.object.filter(user="user1").filter(group="admin").values_list(ids, flat=True).allow_filtering()
    response_list = []
    unquie_ids = list(set(ids))
    for ids in unique_ids:
        response = database_model.object.filter(ids=ids).limit(1)
        for res in response:
            temp_dict = {}
            temp_dict['name'] = res.name
            temp_dict['description'] = res.description
            response_list.append(temp_dict)
   return response_list

这很有效。我想为此编写单元测试用例。 由于相同的database_model需要两次返回值。它对我不起作用。

  @patch('database_model')
  def test_function(mock_model):
      mock_model.objects.filter.return_value.filter.return_value.values_list.return_value.allow_filtering_return_value = [Mock_id]
      mock_model.objects.filter.limit.return_value = mock_dict

      response = function()

      assert len(response) > 0

mock_id和mock_dict是为测试用例创建的值。 我的问题是我第一次将mock_model.objects.filter.return_value.filter.return_value.values_list.return_value.allow_filtering.return_value的return_value分配给[Mock_id]并正确分配。但是下一行我试图再次将return_value分配给同一个方法。这需要一个神奇的模拟对象。所以我的测试用例失败了,因为它得到一个空列表。我想知道如何为同一个方法分配两个不同的return_values。

1 个答案:

答案 0 :(得分:1)

你应该为side_effect模拟写一个database_model.object.filter,它会为你提供一个Mock(),用于在模拟后返回正确的ids列表以用于循环。

mock_filter_get_ids = Mock()
mock_filter_ids = Mock()
mock_model.objects.filter.side_effect = [mock_filter_get_ids, mock_filter_ids]
mock_filter_get_ids.filter.return_value.values_list.return_value.allow_filtering_return_value = [Mock_id]
mock_filter_ids.limit.return_value = mock_dict

但是...

忘掉它:重构你的代码,至少提取:

database_model.object.filter(user="user1").filter(group="admin").values_list(ids, flat=True).allow_filtering()

类似于get_user_ids()

database_model.object.filter(ids=ids).limit(1)
get_ids_response()中的

您可以模拟新方法并使您的代码更易于阅读,简单的测试意味着几乎每次都能阅读。