Форум сайта python.su
Здравствуйте. mock_open помогает тестировать функции, где открываются файлы. И если файл считывается полностью, то всё работает хорошо (вырезка из доки):
>>> with patch('__main__.open', mock_open(read_data='bibble')) as m: ... with open('foo') as h: ... result = h.read() ... >>> m.assert_called_once_with('foo') >>> assert result == 'bibble'
from mock import patch, mock_open from StringIO import StringIO filedata = """This is line1 and this is line2 and here is line3 """ filedata_for_line = StringIO(filedata) with patch('__main__.open', mock_open(read_data=filedata_for_line)) as m: with open('foo') as f: for line in f: print line with patch('__main__.open', mock_open(read_data=filedata.split('\n'))) as m: with open('foo') as f: for line in f: print line
Отредактировано Master_Sergius (Авг. 13, 2017 14:45:45)
Офлайн
Не работает конструкция
for line in f
for line in f.readlines()
Офлайн
JOHN_16
Не работает конструкция
for line in f
для данного мока. Замени на
for line in f.readlines()
или построчно считывай, и убери StringIO на обычную строку
Офлайн
точного ответа я не знаю. Могу предположить что выкинуть mock_open и написать свою мокирующую функцию: которая бы это умела
Офлайн
Master_SergiusНаверное, mock_open() лезет в __enter__(), __exit__() и в read(). А цикл for вызывает __iter__(), который возвращает итератор строк и вот по нему оно уже гуляет. Так что можешь сделать обычный мок (без mock_open()) для функции open() и там должен возвращаться мок-объект из её return'а, у которого нужно у метода __iter__() подменить return, в который и ставятся строки. Я такое делал где-то давно; помню, что нормально работало.
То есть, ни один из примеров выше не работает. Просто ничего не выводит. Что делать, как быть, кто виноват?
Отредактировано py.user.next (Авг. 14, 2017 12:14:09)
Офлайн
Да, товарищи (или приятней - добрые человеки), вы оба правы. Вот решение:
def create_file_mock(data): mock_obj = mock.mock_open(read_data=data) mock_obj.return_value.__iter__.return_value = data.splitlines() return mock_obj with mock.patch('__builtin__.open', create_file_mock(filedata)) as m: with open('foo') as f: for line in f: print line
Офлайн