5

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!

imiric
  • 8,315
  • 4
  • 35
  • 39
  • Could you provide a full self-contained example and include the versions of libraries you are using? I haven't used flexmock but your fixture looks good on first side. When i tried to run it i got ``and_return() got an unexpected keyword argument 'read'``. – hpk42 Nov 18 '13 at 20:16

1 Answers1

14

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
falsetru
  • 357,413
  • 63
  • 732
  • 636
  • Thanks, I'll give it a try, but I really prefer flexmock's API. If I can't figure it out, I'll accept your answer. – imiric Oct 31 '13 at 14:05
  • @imiric, Did you figure it out how to do it with flexmock? – falsetru May 08 '15 at 22:13
  • 1
    Sorry for the delay with accepting your answer. I don't remember getting this to work with `flexmock`, but these days I do indeed use `mock` exclusively, and as you correctly pointed out, it's pretty straightforward to do. Thanks again! – imiric Dec 17 '15 at 17:40