Code Monkey home page Code Monkey logo

pytest-mock's Introduction

pytest-mock

This plugin installs a mocker fixture which is a thin-wrapper around the patching API provided by the excellent mock package, but with the benefit of not having to worry about undoing patches at the end of a test:

def test_unix_fs(mocker):
    mocker.patch('os.remove')
    UnixFS.rm('file')
    os.remove.assert_called_once_with('file')

python version downloads ci appveyor coverage

Usage

The mocker fixture has the same API as mock.patch, supporting the same arguments:

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

The supported methods are:

Some objects from the mock module are accessible directly from mocker so you don't have to import it:

Note

Although mocker's API is intentionally the same as mock.patch's, its uses as context managers and function decorators are not supported. The purpose of this plugin is to make the use of context managers and function decorators for mocking unnecessary. Indeed, trying to use the functionality in mocker in this manner can lead to non-intuitive errors:

def test_context_manager(mocker):
    a = A()
    with mocker.patch.object(a, 'doIt', return_value=True, autospec=True):
        assert a.doIt() == True
================================== FAILURES ===================================
____________________________ test_context_manager _____________________________
in test_context_manager
    with mocker.patch.object(a, 'doIt', return_value=True, autospec=True):
E   AttributeError: __exit__

Spy

New in version 0.6

The spy acts exactly like the original method in all cases, except it allows use of mock features with it, like retrieving call count.

From version 0.7 onward it also works for class and static methods. Originally it was only safe to use with instance methods.

def test_spy(mocker):
    class Foo(object):
        def bar(self):
            return 42

    foo = Foo()
    mocker.spy(foo, 'bar')
    assert foo.bar() == 42
    assert foo.bar.call_count == 1

Stub

New in version 0.6

The stub is a mock object that accepts any arguments and is useful to test callbacks, for instance.

def test_stub(mocker):
    def foo(on_something):
        on_something('foo', 'bar')

    stub = mocker.stub()

    foo(stub)
    stub.assert_called_once_with('foo', 'bar')

Improved reporting of mock call assertion errors

New in version 0.10

This plugin monkeypatches the mock library to improve pytest output for failures of mock call assertions like Mock.assert_called_with(). This is probably safe, but if you encounter any problems this feature can be disabled in your pytest.ini file:

[pytest]
mock_traceback_monkeypatch = false

Note

Prior to version 0.4.0, the mocker fixture was named mock. This was changed because naming the fixture mock conflicts with the actual mock module, which made using it awkward when access to both the module and the plugin were required within a test.

The old fixture mock still works, but its use is discouraged and will be removed in version 1.0.

Requirements

  • Python 2.6+, Python 3.4+
  • pytest
  • mock (for Python 2)

Install

Install using pip:

$ pip install pytest-mock

Changelog

Please consult the changelog page.

Why bother with a plugin?

There are a number of different patch usages in the standard mock API, but IMHO they don't scale very well when you have more than one or two patches to apply.

It may lead to an excessive nesting of with statements, breaking the flow of the test:

import mock

def test_unix_fs():
    with mock.patch('os.remove'):
        UnixFS.rm('file')
        os.remove.assert_called_once_with('file')

        with mock.patch('os.listdir'):
            assert UnixFS.ls('dir') == expected
            # ...

    with mock.patch('shutil.copy'):
        UnixFS.cp('src', 'dst')
        # ...

One can use patch as a decorator to improve the flow of the test:

@mock.patch('os.remove')
@mock.patch('os.listdir')
@mock.patch('shutil.copy')
def test_unix_fs(mocked_copy, mocked_listdir, mocked_remove):
    UnixFS.rm('file')
    os.remove.assert_called_once_with('file')

    assert UnixFS.ls('dir') == expected
    # ...

    UnixFS.cp('src', 'dst')
    # ...

But this poses a few disadvantages:

  • test functions must receive the mock objects as parameter, even if you don't plan to access them directly; also, order depends on the order of the decorated patch functions;
  • receiving the mocks as parameters doesn't mix nicely with pytest's approach of naming fixtures as parameters, or pytest.mark.parametrize;
  • you can't easily undo the mocking during the test execution;

pytest-mock's People

Contributors

nicoddemus avatar fogo avatar tigarmo avatar satyrius avatar chronial avatar the-compiler avatar jespino avatar jurko-gospodnetic avatar ronnypfannschmidt avatar marcwebbie avatar

Watchers

Daniel Hahler avatar James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.