imiric
imiric

Reputation: 9010

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!

Upvotes: 5

Views: 4776

Answers (1)

falsetru
falsetru

Reputation: 368894

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

Upvotes: 14

Related Questions