I have a process that executes a method, let's say called 'save_details', which runs a loop to go out to an external source twice. I want to be able to mock the two responses that would be returned to 'save_details', to give me two different IDs. I can do it when I have one response, but it doesn't seem to work when I need two mock responses to be returned.
So I have the following example fixtures.
Mock 1
@pytest.fixture
def test_201_mock1(mocker) -> None:
"""
Test return data for the 201 response.
"""
mocker.patch(
"save_details",
return_value=[
"201",
{
"ACK": {
"id": "e944126b-db78-4711-9f97-83c2cd1e09a4",
}
},
],
)
Mock 2
@pytest.fixture
def test_201_mock2(mocker) -> None:
"""
Test return data for the 201 response.
"""
mocker.patch(
"save_details",
return_value=[
"201",
{
"ACK": {
"id": "4758a428-8f33-4dc8-bb64-a500855f9a8c",
}
},
],
)
And I have my test:
async def test_create_valid_resource_201(
test_201_mock1,
test_201_mock2,
...
) -> None:
"""
Tests if a valid POST request returns a 201 response.
"""
#rest of test
...
The 'test_create_valid_resource_201' test will simply run the 'save_details' method I have. What happens is I basically get the ID from test_201_mock2 duplicated.
4758a428-8f33-4dc8-bb64-a500855f9a8c
4758a428-8f33-4dc8-bb64-a500855f9a8c
How would I get pytest to recognise that there are two mocks to be returned, one for each iteration of my loop in 'save_details'? Do I create one mock with the two responses for example?
CodePudding user response:
Side effect is meant just for this purpose - it can be used to return different values in the same mock. This example is taken from the documentation - 3 consecutive calls to the mock would produce different results as specified in side_effect:
>>> mock = MagicMock()
>>> mock.side_effect = [5, 4, 3, 2, 1]
>>> mock(), mock(), mock()
(5, 4, 3)
In your example you can have a single fixture to set the side_effect
like so:
@pytest.fixture
def test_201_mock(mocker) -> None:
"""
Test return data for the 201 response.
"""
mocker.patch(
"save_details",
side_effect=[
["201",
{
"ACK": {
"id": "e944126b-db78-4711-9f97-83c2cd1e09a4",
}
}],
["201",
{
"ACK": {
"id": "4758a428-8f33-4dc8-bb64-a500855f9a8c",
}
}]
],
)