2012-01-05 3 views
4

Я использую python-mock, чтобы издеваться над открытым файлом. Я хотел бы иметь возможность передавать поддельные данные таким образом, поэтому я могу проверить, что вызывается read(), а также используя тестовые данные, не ударяя файловую систему при тестировании.Получение фактического возвращаемого значения для mocked file.read()

Вот что у меня до сих пор:

file_mock = MagicMock(spec=file) 
file_mock.read.return_value = 'test' 

with patch('__builtin__.open', create=True) as mock_open: 
    mock_open.return_value = file_mock 

    with open('x') as f: 
     print f.read() 

Выход этого <mock.Mock object at 0x8f4aaec> Intead из 'test', как я предполагаю. Что я делаю неправильно в построении этого макета?

Edit:

выглядит так:

with open('x') as f: 
    f.read() 

и это:

f = open('x') 
f.read() 

являются разные объекты. Использование mock в качестве менеджера контекста заставляет его возвращать новый Mock, тогда как вызов его напрямую возвращает все, что я определил в mock_open.return_value. Есть идеи?

ответ

9

Это звучит как хороший прецедент для объекта StringIO, который уже реализует интерфейс файла. Возможно, вы можете сделать file_mock = MagicMock(spec=file, wraps=StringIO('test')). Или вы могли бы просто заставить вашу функцию принять файл-подобный объект и передать ему StringIO вместо реального файла, избегая необходимости в уродливых исправлениях обезьян.

Вы посмотрели фальшивую документацию?

http://www.voidspace.org.uk/python/mock/compare.html#mocking-the-builtin-open-used-as-a-context-manager

+0

Я попытался Мессинг вокруг некоторых это. Похоже, что mock_open возвращает другой объект, когда он используется в диспетчере контекста или напрямую вызван. Я обновил свой вопрос. Есть идеи? –

+0

обновленный ответ. –

+0

Я прочитал верхнюю половину этой страницы, но пропустил нижнюю половину по неизвестной причине. Герп и дерп. –

6

В Python 3 шаблон просто:

>>> import unittest.mock as um 
>>> with um.patch('builtins.open', um.mock_open(read_data='test')): 
...  with open('/dev/null') as f: 
...   print(f.read()) 
... 
test 
>>> 

(Да, вы можете даже издеваться/DEV/нуль, чтобы вернуть содержимое файла.)

Смежные вопросы