2013-10-27 4 views
4

Я пытаюсь использовать pytest-приспособления, чтобы высмеять вызовы на open(), а затем сбросить его на тестовом отрыве, но по какой-то причине макет не применяется в тестовой функции.Mocking не работает с pytest и flexmock

Вот пример того, что у меня есть:

# tests.py 
@pytest.fixture(scope='module') 
def mock_open(request): 
    mock = flexmock(sys.modules['__builtin__']) 
    mock.should_call('open') 
    m = (mock.should_receive('open') 
     .with_args('/tmp/somefile') 
     .and_return(read=lambda: 'file contents')) 
    request.addfinalizer(lambda: m.reset()) 

def test_something(mock_open): 
    ret = function_to_test() 
    ret[1]() # This actually uses the original open() 

И, в случае, если это важно, вот что function_to_test() выглядит следующим образом:

# some_module.py 
def function_to_test(): 
    def inner_func(): 
     open('/tmp/somefile').read() # <-- I want this call mocked 
     # More code ... 
    return (True, inner_func) 

Это также происходит, если я использую XUnit стиле setup_module()/teardown_module() функции. Но если я вставляю издевательский код внутри самой тестовой функции (чего я, очевидно, не хочу делать), то она отлично работает.

Что мне не хватает? Благодаря!

+0

могли бы вы предоставить полный автономный пример и включают в себя версии библиотек, которые вы используете? Я не использовал flexmock, но ваш прибор выглядит хорошо на первой стороне. Когда я попытался запустить его, я получил '' and_return() получил неожиданный аргумент ключевого слова 'read'''. – hpk42

ответ

13

Как насчет использования mock?


tests.py:

import mock # import unittest.mock (Python 3.3+) 
import pytest 

from some_module import function_to_test 

@pytest.fixture(scope='function') 
def mock_open(request): 
    m = mock.patch('__builtin__.open', mock.mock_open(read_data='file content')) 
    m.start() 
    request.addfinalizer(m.stop) 

def test_something(mock_open): 
    ret = function_to_test() 
    assert ret[1]() == 'file content' 

some_module.py:

def function_to_test(): 
    def inner_func(): 
     return open('/tmp/somefile').read() 
    return True, inner_func 
+0

Спасибо, я попробую, но я действительно предпочитаю API flexmock. Если я не смогу понять это, я приму свой ответ. – imiric

+0

@imiric, вы выяснили, как это сделать с помощью flexmock? – falsetru

+1

Извините за задержку с принятием вашего ответа. Я не помню, чтобы это работало с «flexmock», но в наши дни я действительно использую «mock» исключительно, и, как вы правильно указали, это довольно просто. Еще раз спасибо! – imiric

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