Как с помощью pytest протестировать запись в CSV на уровне формируемых им строк без записи в файл?
Прошу подсказать как мне протестировать функцию записи в csv-файл не записывая в файл, а поставив mock-объект в тот момент, когда очередная строчка уже сформирована?
from csv import DictWriter
def write_to_csv(filename, address, opcode) -> None:
with open(filename, 'w', newline='') as csv_file:
writer = DictWriter(csv_file, fieldnames=(
'address', 'opcode'))
writer.writeheader()
writer.writerow({'address': address,
'opcode': opcode})
Вот псевдокод того что хочу получить:
def test_write_to_csv():
class CSVWriter:
def write(row):
self.row = row
csv_writer = CSVWriter()
with monkeypatch(DictWriter, csv_writer):
write_to_csv('opcodes.csv', 0xDA, 5)
assert '0xDA,5' == csv_writer.row
В этом куске псевдокод я:
- Создал патч-объект для накапливания сформированных строк для записи в CSV-файл
- Я патчу стандартный объект
DictWriter
передав ему свой патч-объект, который накапливает строки - После вызываю тестируемую функцию
write_to_csv
- После выполнения тестируемой функции я проверяю результаты ее работы
Мой пример специально сужен до такого примитивного кода, чтоб проще было пояснить чего хочу добиться. Мне нужно в чужом проекте, править код которого у меня нет возможности протестировать запись CSV-файлы большого количества значений не ухудшив скорость работы автотестов. По этому мне очень хочется избежать фактических I/O операций и проверить итоговые csv-строки накопив их в памяти.
Мне непонятно как мне мой тест на псеводкоде превратить в работающий код. Как написать такой monkeypath-код, который патчит в тестовых целях стандартный модуль csv
?
Ответы (1 шт):
Вот так можно мокнуть open
и проверить результаты его работы:
from unittest import mock
import pytest
from csv import DictWriter
def write_to_csv(filename, address, opcode) -> None:
with open(filename, 'w', newline='') as csv_file:
writer = DictWriter(csv_file, fieldnames=(
'address', 'opcode'))
writer.writeheader()
writer.writerow({'address': address,
'opcode': opcode})
def test():
with mock.patch('builtins.open', mock.mock_open()) as open_:
write_to_csv('opcodes.csv', 0xDA, 5)
open_.assert_called_once_with('opcodes.csv', 'w', newline='')
assert open_().write.call_args_list == [
mock.call('address,opcode\r\n'),
mock.call('218,5\r\n')
]