Pytest works with old mock, but not unittest.mock
<p>I'm porting some code from Python 2 to 3, and <code>py.test</code> isn't playing well with the <code>patch</code> decorator from <code>unittest.mock</code>. When I use the <code>patch</code> decorator to pass a mock into the arguments of a test function, <code>py.test</code> instead interprets that argument to be a fixture, and is unable to set up the test.</p>

<p>Here's a contrived example that hopefully illuminates the problem:</p>

<pre><code>@patch('my_module.my_func')
def test_my_func(mock_func):
    mock_func()
    mock_func.assert_called_once_with()
</code></pre>

<p>After running <code>py.test</code>, the error message would look like:</p>

<pre><code>E       fixture 'my_func' not found
&gt;       available fixtures: cache, capfd, capsys, doctest_namespace, monkeypatch, pytestconfig, record_xml_property, recwarn, tmpdir, tmpdir_factory
&gt;       use 'pytest --fixtures [testpath]' for help on them.
</code></pre>

<p>This is the only scenario under which this failure occurs. If I explicitly call the test (i.e. run <code>test_my_func()</code>), no error. If I patch <code>my_func</code> using either of the other patching techniques, no error. If I import patch from <code>mock</code> instead of <code>unittest.mock</code>, no error.</p>

<p>It's only while running my tests using <code>py.test</code>, using <code>unittest.mock</code>, and patching using the decorator when this occurs.</p>

<p>I'm running Python 3.4.5.</p>

<p>Yes, mock decorators are not supported.
It's not such bad -- changing function signature by decorator appliance is considered as bad idea.
But you still  may use <code>with mock.patch(...)</code> syntax.</p>

<p>Also as an option there is <a href="https://pypi.python.org/pypi/pytest-mock" rel="nofollow">pytest-mock</a> plugin with pretty clean api for mocking:</p>

<pre><code>def test_foo(mocker):
    # all valid calls
    mocker.patch('os.remove')
    mocker.patch.object(os, 'listdir', autospec=True)
    mocked_isfile = mocker.patch('os.path.isfile')
</code></pre>

python unit-testing python-3.x mocking py.test