我有一个使用 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 是为测试用例创建的值。 我的问题是我第一次将 return_value 分配给mock_model.objects.filter.return_value.filter.return_value.values_list.return_value.allow_filtering.return_value 到[Mock_id],它被正确分配。但下一行我尝试再次将 return_value 分配给相同的方法。这作为一个神奇的模拟对象。所以我的测试用例失败了,因为它得到一个空列表。我想知道如何将两个不同的 return_values 分配给同一个方法。
最佳答案
您应该为 database_model.object.filter
模拟编写一个 side_effect
,为您提供配置为返回正确的
在模拟之后列出要在 for 循环中使用的列表。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()
中。
您可以模拟新方法并使代码更易于阅读,易于测试意味着几乎每次都易于阅读。
关于python - 模拟具有不同返回值的相同方法在Python中的函数中调用两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35467515/