Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking not working with pytest and flexmock

I'm trying to use pytest fixtures to mock calls to open() and then reset it on test teardown, but for some reason the mock is not applied in the test function.

Here's a sample of what I have:

# 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()

And, in case it matters, here's what the function_to_test() looks like:

# 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)

This also happens if I use xUnit-style setup_module()/teardown_module() functions. But if I put the mocking code within the test function itself (which I obviously don't want to do), then it works fine.

What am I missing? Thanks!

like image 564
imiric Avatar asked Oct 27 '13 12:10

imiric


1 Answers

How about using 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
like image 110
falsetru Avatar answered Nov 07 '22 07:11

falsetru