Reputation: 73
I have a method to be tested using pytest. The method is calling same database model twice.
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
This works well. I am tring to write unit test case for this. As the same database_model requires return value twice. It does not work for me.
@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 and mock_dict are values created for test case. My question is first time i am assigning a return_value to mock_model.objects.filter.return_value.filter.return_value.values_list.return_value.allow_filtering.return_value to [Mock_id] which gets assigned properly. But the next line i am trying to assign a return_value again to the same method. This takes as a magic mock object. So my test case fails because it is getting a empty list. I would like to know how can i assign two different return_values to the same method.
Upvotes: 3
Views: 8050
Reputation: 23711
You should write a side_effect
for database_model.object.filter
mock that gives you a Mock()
configured to return the correct ids
list after a mock to use in for cycle.
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
Forget it: refactor your code, at least extract:
database_model.object.filter(user="user1").filter(group="admin").values_list(ids, flat=True).allow_filtering()
In something like get_user_ids()
and
database_model.object.filter(ids=ids).limit(1)
in get_ids_response()
.
You can mock the new methods and make your code simpler to read, simple to test means simple to read almost every time.
Upvotes: 2