Pytest: как издеваться над переменной метода класса класса команды управления django
Существует команда менеджера django, которая работает с файлом csv. app/my_app/my_command.py
class Command(BaseCommand):
def handle(self, *args, **options):
path = (os.path.join(os.path.abspath(os.path.dirname(__name__)), 'data.csv'))
# other logic with file
Я пишу тест для этого в pytest, проблема в том, что я не могу понять, как подружить переменную path
для проверки доступа не к реальному data.csv, а к временному test.csv файлу
@pytest.fixture
def create_test_csv_file(tmpdir_factory):
path = tmpdir_factory.mktemp('data').join('test.csv')
# other logic
return str(path)
@pytest.mark.django_db
def test_function(mocker, create_test_csv_file):
# smth like mock_path = create_test_csv_file <- NEW CODE HERE
call_command('my_command')
Вы можете сделать path
аргументом со значением по умолчанию. В тесте вы можете передать путь к тестовому файлу.
class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument(
"--path",
dest="path",
default=os.path.join(os.path.abspath(os.path.dirname(__name__)), 'data.csv')
)
def handle(self, *args, **options):
path = options.get("path")
...
Тогда в тестах вы можете вызывать call_command('my_command', path=<path>)
Вы не можете высмеять локальную переменную path
, но вы можете высмеять место, откуда она была получена, то есть из os.path.join
.
src.py
import os
class Command:
def handle(self):
path = (os.path.join(os.path.abspath(os.path.dirname(__name__)), 'data.csv'))
print(path)
return path
test_src.py
from src import Command
def test_real_path(mocker, tmp_path):
result = Command().handle()
assert str(result).endswith("data.csv") # Real file
def test_mock_path(mocker, tmpdir_factory):
path = tmpdir_factory.mktemp('data').join('test.csv')
mocker.patch("os.path.join", return_value=path) # Or "src.os.path.join"
result = Command().handle()
assert str(result).endswith("test.csv") # Test file
assert result == path
Выход:
$ pytest -q -rP
..
[100%]
================================================================================================= PASSES ==================================================================================================
_____________________________________________________________________________________________ test_real_path ______________________________________________________________________________________________
------------------------------------------------------------------------------------------ Captured stdout call -------------------------------------------------------------------------------------------
/home/nponcian/Documents/data.csv
_____________________________________________________________________________________________ test_mock_path ______________________________________________________________________________________________
------------------------------------------------------------------------------------------ Captured stdout call -------------------------------------------------------------------------------------------
/tmp/pytest-of-nponcian/pytest-15/data0/test.csv
2 passed in 0.06s