Reputation: 166
I'm creating some unit tests and using pytest fixtures in combination with some unittest.mock patch.object
calls.
I would like to reuse a function that is called by some of my tests. It makes use of a pytest fixture (specified as the first "argument" of the function) and it requires an additional argument. It looks something like this:
import pandas as pd
import pytest
import os
from unittest.mock import patch
@pytest.fixture()
def rootdir():
return os.path.dirname(os.path.abspath(__file__))
def my_mock_ret(rootdir, number):
print(f"{rootdir}_{number}")
return f"{rootdir}_{number}"
def test_simple(rootdir):
a = pd.DataFrame()
with patch.object(a, 'to_csv', lambda x: my_mock_ret(rootdir, x)) as _:
a.to_csv(rootdir)
The tricky part is how to pass the number
argument to my_mock_ret
while also being able to access the rootdir
fixture from inside it.
I've tried this way using lambda but it does not work.
It works if y put my_mock_ret
inside test_simple
, but I don't want to do that because I want to reuse my_mock_ret
for several other tests:
import pandas as pd
import pytest
import os
from unittest.mock import patch
@pytest.fixture()
def rootdir():
return os.path.dirname(os.path.abspath(__file__))
def test_simple(rootdir):
def my_mock_ret(number):
print(f"{rootdir}_{number}")
return f"{rootdir}_{number}"
a = pd.DataFrame()
with patch.object(a, 'to_csv', my_mock_ret) as _:
a.to_csv(rootdir)
Upvotes: 0
Views: 120
Reputation: 5152
What you need right here, is the factory pattern:
import pandas as pd
import pytest
import os
from unittest.mock import patch
@pytest.fixture()
def rootdir():
return os.path.dirname(os.path.abspath(__file__))
@pytest.fixture()
def my_mock_ret(rootdir):
def _my_mock_ret(number):
print(f"{rootdir}_{number}")
return f"{rootdir}_{number}"
return _my_mock_ret
def test_simple(my_mock_ret, rootdir):
a = pd.DataFrame()
with patch.object(a, 'to_csv', my_mock_ret) as _:
a.to_csv(rootdir)
here my_mock_ret
will create a function, which captures rootdir
, and can take the number
argument.
Upvotes: 1