diff --git a/Doc/library/unittest.mock-examples.rst b/Doc/library/unittest.mock-examples.rst index 05f33740d7527a9..e1bcb50dbc57913 100644 --- a/Doc/library/unittest.mock-examples.rst +++ b/Doc/library/unittest.mock-examples.rst @@ -6,6 +6,11 @@ .. versionadded:: 3.3 +.. testsetup:: + + import unittest + from unittest.mock import MagicMock, sentinel, patch + .. _getting-started: @@ -23,6 +28,9 @@ Common uses for :class:`Mock` objects include: You might want to replace a method on an object to check that it is called with the correct arguments by another part of the system: +.. doctest:: + :options: +SKIP + >>> real = SomeClass() >>> real.method = MagicMock(name='method') >>> real.method(3, 4, 5, key='value') @@ -77,6 +85,7 @@ an object then it calls ``close`` on it. So to test it we need to pass in an object with a ``close`` method and check that it was called correctly. + >>> from unittest.mock import Mock >>> real = ProductionClass() >>> mock = Mock() >>> real.closer(mock) @@ -101,6 +110,9 @@ and calls a method on it. The call to :func:`patch` replaces the class ``Foo`` w mock. The ``Foo`` instance is the result of calling the mock, so it is configured by modifying the mock :attr:`~Mock.return_value`. +.. doctest:: + :options: +SKIP + >>> def some_function(): ... instance = module.Foo() ... return instance.method() @@ -149,6 +161,7 @@ that they were made in the right order and with no additional calls: You use the :data:`call` object to construct lists for comparing with ``mock_calls``: + >>> from unittest.mock import call >>> expected = [call.method(), call.attribute.method(10, x=53)] >>> mock.mock_calls == expected True @@ -271,6 +284,9 @@ attribute error. If you change the implementation of your specification, then tests that use that class will start failing immediately without you having to instantiate the class in those tests. +.. doctest:: + :options: +SKIP + >>> mock = Mock(spec=SomeClass) >>> mock.old_method() Traceback (most recent call last): @@ -323,6 +339,9 @@ with. ``patch.object``: +.. doctest:: + :options: +SKIP + >>> original = SomeClass.attribute >>> @patch.object(SomeClass, 'attribute', sentinel.attribute) ... def test(): @@ -341,6 +360,9 @@ with. If you are patching a module (including :mod:`builtins`) then use :func:`patch` instead of :func:`patch.object`: +.. doctest:: + :options: +SKIP + >>> mock = MagicMock(return_value=sentinel.file_handle) >>> with patch('builtins.open', mock): ... handle = open('filename', 'r') @@ -350,6 +372,9 @@ instead of :func:`patch.object`: The module name can be 'dotted', in the form ``package.module`` if needed: +.. doctest:: + :options: +SKIP + >>> @patch('package.module.ClassName.attribute', sentinel.attribute) ... def test(): ... from package.module import ClassName @@ -359,6 +384,9 @@ The module name can be 'dotted', in the form ``package.module`` if needed: A nice pattern is to actually decorate test methods themselves: +.. doctest:: + :options: +SKIP + >>> class MyTest(unittest.TestCase): ... @patch.object(SomeClass, 'attribute', sentinel.attribute) ... def test_something(self): @@ -372,6 +400,9 @@ If you want to patch with a Mock, you can use :func:`patch` with only one argume (or :func:`patch.object` with two arguments). The mock will be created for you and passed into the test function / method: +.. doctest:: + :options: +SKIP + >>> class MyTest(unittest.TestCase): ... @patch.object(SomeClass, 'static_method') ... def test_something(self, mock_method): @@ -389,7 +420,7 @@ You can stack up multiple patch decorators using this pattern: ... self.assertIs(package.module.ClassName1, MockClass1) ... self.assertIs(package.module.ClassName2, MockClass2) ... - >>> MyTest('test_something').test_something() + >>> MyTest('test_something').test_something() # doctest: +SKIP When you nest patch decorators the mocks are passed in to the decorated function in the same order they applied (the normal *python* order that @@ -460,6 +491,9 @@ testable way in the first place... So, suppose we have some code that looks a little bit like this: +.. doctest:: + :options: +SKIP + >>> class Something: ... def __init__(self): ... self.backend = BackendProvider() @@ -487,6 +521,9 @@ response object for it. To set the response as the return value for that final We can do that in a slightly nicer way using the :meth:`~Mock.configure_mock` method to directly set the return value for us: +.. doctest:: + :options: +SKIP + >>> something = Something() >>> mock_response = Mock(spec=open) >>> mock_backend = Mock() @@ -496,6 +533,9 @@ method to directly set the return value for us: With these we monkey patch the "mock backend" in place and can make the real call: +.. doctest:: + :options: +SKIP + >>> something.backend = mock_backend >>> something.method() @@ -504,6 +544,9 @@ assert. A chained call is several calls in one line of code, so there will be several entries in ``mock_calls``. We can use :meth:`call.call_list` to create this list of calls for us: +.. doctest:: + :options: +SKIP + >>> chained = call.get_endpoint('foobar').create_call('spam', 'eggs').start_call() >>> call_list = chained.call_list() >>> assert mock_backend.mock_calls == call_list @@ -527,6 +570,9 @@ attribute on the mock date class is then set to a lambda function that returns a real date. When the mock date class is called a real date will be constructed and returned by ``side_effect``. +.. doctest:: + :options: +SKIP + >>> from datetime import date >>> with patch('mymodule.date') as mock_date: ... mock_date.today.return_value = date(2010, 10, 8) @@ -602,6 +648,9 @@ various forms) as a class decorator. This applies the patches to all test methods on the class. A test method is identified by methods whose names start with ``test``: +.. doctest:: + :options: +SKIP + >>> @patch('mymodule.SomeClass') ... class MyTest(TestCase): ... @@ -622,7 +671,7 @@ with ``test``: An alternative way of managing patches is to use the :ref:`start-and-stop`. These allow you to move the patching into your ``setUp`` and ``tearDown`` methods. - >>> class MyTest(TestCase): + >>> class MyTest(unittest.TestCase): ... def setUp(self): ... self.patcher = patch('mymodule.foo') ... self.mock_foo = self.patcher.start() @@ -633,14 +682,14 @@ These allow you to move the patching into your ``setUp`` and ``tearDown`` method ... def tearDown(self): ... self.patcher.stop() ... - >>> MyTest('test_foo').run() + >>> MyTest('test_foo').run() # doctest: +SKIP If you use this technique you must ensure that the patching is "undone" by calling ``stop``. This can be fiddlier than you might think, because if an exception is raised in the setUp then tearDown is not called. :meth:`unittest.TestCase.addCleanup` makes this easier: - >>> class MyTest(TestCase): + >>> class MyTest(unittest.TestCase): ... def setUp(self): ... patcher = patch('mymodule.foo') ... self.addCleanup(patcher.stop) @@ -649,7 +698,7 @@ exception is raised in the setUp then tearDown is not called. ... def test_foo(self): ... self.assertIs(mymodule.foo, self.mock_foo) ... - >>> MyTest('test_foo').run() + >>> MyTest('test_foo').run() # doctest: +SKIP Mocking Unbound Methods @@ -755,6 +804,9 @@ defined in 'mymodule':: When we try to test that ``grob`` calls ``frob`` with the correct argument look what happens: +.. doctest:: + :options: +SKIP + >>> with patch('mymodule.frob') as mock_frob: ... val = {6} ... mymodule.grob(val) @@ -779,6 +831,9 @@ example I'm using *another* mock to store the arguments so that I can use the mock methods for doing the assertion. Again a helper function sets this up for me. +.. doctest:: + :options: +SKIP + >>> from copy import deepcopy >>> from unittest.mock import Mock, patch, DEFAULT >>> def copy_call_args(mock): @@ -856,7 +911,10 @@ Using patch as a context manager is nice, but if you do multiple patches you can end up with nested with statements indenting further and further to the right: - >>> class MyTest(TestCase): +.. doctest:: + :options: +SKIP + + >>> class MyTest(unittest.TestCase): ... ... def test_foo(self): ... with patch('mymodule.Foo') as mock_foo: @@ -875,7 +933,10 @@ achieve the same effect without the nested indentation. A simple helper method, ``create_patch``, puts the patch in place and returns the created mock for us: - >>> class MyTest(TestCase): +.. doctest:: + :options: +SKIP + + >>> class MyTest(unittest.TestCase): ... ... def create_patch(self, name): ... patcher = patch(name) @@ -968,7 +1029,7 @@ mock methods and attributes: [call('a'), call('c'), call('d'), call('b'), call('d')] >>> mock.__setitem__.call_args_list [call('b', 'fish'), call('d', 'eggs')] - >>> my_dict + >>> my_dict # doctest: +SKIP {'a': 1, 'c': 3, 'b': 'fish', 'd': 'eggs'} @@ -1070,6 +1131,7 @@ Here's an example that mocks out the 'fooble' module. ... fooble.blob() ... + >>> import sys >>> assert 'fooble' not in sys.modules >>> mock.blob.assert_called_once_with() @@ -1134,6 +1196,9 @@ If ``patch`` is creating, and putting in place, your mocks then you can attach them to a manager mock using the :meth:`~Mock.attach_mock` method. After attaching calls will be recorded in ``mock_calls`` of the manager. +.. doctest:: + :options: +SKIP + >>> manager = MagicMock() >>> with patch('mymodule.Class1') as MockClass1: ... with patch('mymodule.Class2') as MockClass2: diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index cbe0c9adb8a37bf..c5e42b7abb41013 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -10,6 +10,13 @@ .. versionadded:: 3.3 +.. testsetup:: + + import unittest + from unittest.mock import MagicMock, PropertyMock, patch + from urllib import request + + **Source code:** :source:`Lib/unittest/mock.py` -------------- @@ -46,6 +53,9 @@ methods as you access them and store details of how they have been used. You can configure them, to specify return values or limit what attributes are available, and then make assertions about how they have been used: +.. doctest:: + :options: +SKIP + >>> from unittest.mock import MagicMock >>> thing = ProductionClass() >>> thing.method = MagicMock(return_value=3) @@ -56,6 +66,7 @@ available, and then make assertions about how they have been used: :attr:`side_effect` allows you to perform side effects, including raising an exception when a mock is called: + >>> from unittest.mock import Mock >>> mock = Mock(side_effect=KeyError('foo')) >>> mock() Traceback (most recent call last): @@ -82,6 +93,9 @@ The :func:`patch` decorator / context manager makes it easy to mock classes or objects in a module under test. The object you specify will be replaced with a mock (or other object) during the test and restored when the test ends: +.. doctest:: + :options: +SKIP + >>> from unittest.mock import patch >>> @patch('module.ClassName2') ... @patch('module.ClassName1') @@ -109,6 +123,9 @@ mock (or other object) during the test and restored when the test ends: As well as a decorator :func:`patch` can be used as a context manager in a with statement: +.. doctest:: + :options: +SKIP + >>> with patch.object(ProductionClass, 'method', return_value=None) as mock_method: ... thing = ProductionClass() ... thing.method(1, 2, 3) @@ -348,6 +365,7 @@ the *new_callable* argument to :func:`patch`. >>> mock(2) >>> mock(3) >>> mock(4) + >>> from unittest.mock import call >>> calls = [call(2), call(3)] >>> mock.assert_has_calls(calls) >>> calls = [call(4), call(2), call(3)] @@ -503,6 +521,7 @@ the *new_callable* argument to :func:`patch`. The default return value is a mock object and you can configure it in the normal way: + >>> from unittest.mock import sentinel >>> mock = Mock() >>> mock.return_value.attribute = sentinel.Attribute >>> mock.return_value() @@ -553,6 +572,7 @@ the *new_callable* argument to :func:`patch`. Using a callable: + >>> from unittest.mock import DEFAULT >>> mock = Mock(return_value=3) >>> def side_effect(*args, **kwargs): ... return DEFAULT @@ -709,6 +729,9 @@ the *new_callable* argument to :func:`patch`. Mock objects that use a class or an instance as a :attr:`spec` or :attr:`spec_set` are able to pass :func:`isinstance` tests: +.. doctest:: + :options: +SKIP + >>> mock = Mock(spec=SomeClass) >>> isinstance(mock, SomeClass) True @@ -776,6 +799,9 @@ apply to method calls on the mock object. Fetching a :class:`PropertyMock` instance from an object calls the mock, with no args. Setting it calls the mock with the value being set. + .. doctest:: + :options: +SKIP + >>> class Foo: ... @property ... def foo(self): @@ -1003,6 +1029,9 @@ Mocks created for you by :func:`patch` are automatically given names. To attach mocks that have names to a parent you use the :meth:`~Mock.attach_mock` method: +.. doctest:: + :options: +SKIP + >>> thing1 = object() >>> thing2 = object() >>> parent = MagicMock() @@ -1119,6 +1148,9 @@ patch :func:`patch` as function decorator, creating the mock for you and passing it into the decorated function: +.. doctest:: + :options: +SKIP + >>> @patch('__main__.SomeClass') ... def function(normal_argument, mock_class): ... print(mock_class is SomeClass) @@ -1137,6 +1169,9 @@ can set the *return_value* to be anything you want. To configure return values on methods of *instances* on the patched class you must do this on the :attr:`return_value`. For example: +.. doctest:: + :options: +SKIP + >>> class Class: ... def method(self): ... pass @@ -1151,6 +1186,9 @@ you must do this on the :attr:`return_value`. For example: If you use *spec* or *spec_set* and :func:`patch` is replacing a *class*, then the return value of the created mock will have the same spec. +.. doctest:: + :options: +SKIP + >>> Original = Class >>> patcher = patch('__main__.Class', spec=True) >>> MockClass = patcher.start() @@ -1162,6 +1200,9 @@ The *new_callable* argument is useful where you want to use an alternative class to the default :class:`MagicMock` for the created mock. For example, if you wanted a :class:`NonCallableMock` to be used: +.. doctest:: + :options: +SKIP + >>> thing = object() >>> with patch('__main__.thing', new_callable=NonCallableMock) as mock_thing: ... assert thing is mock_thing @@ -1189,6 +1230,9 @@ you need to do is to configure the mock. Some of that configuration can be done in the call to patch. Any arbitrary keywords you pass into the call will be used to set attributes on the created mock: +.. doctest:: + :options: +SKIP + >>> patcher = patch('__main__.thing', first='one', second='two') >>> mock_thing = patcher.start() >>> mock_thing.first @@ -1202,6 +1246,9 @@ also be configured. These aren't syntactically valid to pass in directly as keyword arguments, but a dictionary with these as keys can still be expanded into a :func:`patch` call using ``**``: +.. doctest:: + :options: +SKIP + >>> config = {'method.return_value': 3, 'other.side_effect': KeyError} >>> patcher = patch('__main__.thing', **config) >>> mock_thing = patcher.start() @@ -1238,6 +1285,9 @@ When calling with the two argument form you omit the replacement object, and a mock is created for you and passed in as an extra argument to the decorated function: +.. doctest:: + :options: +SKIP + >>> @patch.object(SomeClass, 'class_method') ... def test(mock_method): ... SomeClass.class_method(3) @@ -1361,9 +1411,11 @@ If you want :func:`patch.multiple` to create mocks for you, then you can use :data:`DEFAULT` as the value. If you use :func:`patch.multiple` as a decorator then the created mocks are passed into the decorated function by keyword. +.. doctest:: + :options: +SKIP + >>> thing = object() >>> other = object() - >>> @patch.multiple('__main__', thing=DEFAULT, other=DEFAULT) ... def test_function(thing, other): ... assert isinstance(thing, MagicMock) @@ -1374,6 +1426,9 @@ then the created mocks are passed into the decorated function by keyword. :func:`patch.multiple` can be nested with other ``patch`` decorators, but put arguments passed by keyword *after* any of the standard arguments created by :func:`patch`: +.. doctest:: + :options: +SKIP + >>> @patch('sys.exit') ... @patch.multiple('__main__', thing=DEFAULT, other=DEFAULT) ... def test_function(mock_exit, other, thing): @@ -1386,6 +1441,9 @@ passed by keyword *after* any of the standard arguments created by :func:`patch` If :func:`patch.multiple` is used as a context manager, the value returned by the context manger is a dictionary where created mocks are keyed by name: +.. doctest:: + :options: +SKIP + >>> with patch.multiple('__main__', thing=DEFAULT, other=DEFAULT) as values: ... assert 'other' in repr(values['other']) ... assert 'thing' in repr(values['thing']) @@ -1410,6 +1468,9 @@ call :meth:`start` to put the patch in place and :meth:`stop` to undo it. If you are using :func:`patch` to create a mock for you then it will be returned by the call to ``patcher.start``. +.. doctest:: + :options: +SKIP + >>> patcher = patch('package.module.ClassName') >>> from package import module >>> original = module.ClassName @@ -1424,7 +1485,7 @@ the call to ``patcher.start``. A typical use case for this might be for doing multiple patches in the ``setUp`` method of a :class:`TestCase`: - >>> class MyTest(TestCase): + >>> class MyTest(unittest.TestCase): ... def setUp(self): ... self.patcher1 = patch('package.module.Class1') ... self.patcher2 = patch('package.module.Class2') @@ -1439,7 +1500,7 @@ method of a :class:`TestCase`: ... assert package.module.Class1 is self.MockClass1 ... assert package.module.Class2 is self.MockClass2 ... - >>> MyTest('test_something').run() + >>> MyTest('test_something').run() # doctest: +SKIP .. caution:: @@ -1448,7 +1509,7 @@ method of a :class:`TestCase`: exception is raised in the ``setUp`` then ``tearDown`` is not called. :meth:`unittest.TestCase.addCleanup` makes this easier: - >>> class MyTest(TestCase): + >>> class MyTest(unittest.TestCase): ... def setUp(self): ... patcher = patch('package.module.Class') ... self.MockClass = patcher.start() @@ -1476,6 +1537,9 @@ patch builtins You can patch any builtins within a module. The following example patches builtin :func:`ord`: +.. doctest:: + :options: +SKIP + >>> @patch('__main__.ord') ... def test(mock_ord): ... mock_ord.return_value = 101 @@ -1496,6 +1560,9 @@ start with ``'test'`` as being test methods. This is the same way that the It is possible that you want to use a different prefix for your tests. You can inform the patchers of the different prefix by setting ``patch.TEST_PREFIX``: +.. doctest:: + :options: +SKIP + >>> patch.TEST_PREFIX = 'foo' >>> value = 3 >>> @@ -1523,6 +1590,9 @@ decorators. You can stack up multiple patch decorators using this pattern: +.. doctest:: + :options: +SKIP + >>> @patch.object(SomeClass, 'class_method') ... @patch.object(SomeClass, 'static_method') ... def test(mock1, mock2): @@ -1843,6 +1913,9 @@ creating and testing the identity of objects like this. In this example we monkey patch ``method`` to return ``sentinel.some_object``: +.. doctest:: + :options: +SKIP + >>> real = ProductionClass() >>> real.method = Mock(name="method") >>> real.method.return_value = sentinel.some_object @@ -1930,7 +2003,7 @@ arguments are a dictionary: >>> args, kwargs = kall >>> args (1, 2, 3) - >>> kwargs + >>> kwargs # doctest: +SKIP {'arg2': 'two', 'arg': 'one'} >>> args is kall[0] True @@ -1946,7 +2019,7 @@ arguments are a dictionary: 'foo' >>> args (4, 5, 6) - >>> kwargs + >>> kwargs # doctest: +SKIP {'arg2': 'three', 'arg': 'two'} >>> name is m.mock_calls[0][0] True @@ -1994,6 +2067,7 @@ To ignore certain arguments you can pass in objects that compare equal to :meth:`~Mock.assert_called_once_with` will then succeed no matter what was passed in. + >>> from unittest.mock import ANY >>> mock = Mock(return_value=None) >>> mock('foo', bar=object()) >>> mock.assert_called_once_with('foo', bar=ANY) @@ -2027,6 +2101,9 @@ If the mock was created with a *spec* (or *autospec* of course) then all the attributes from the original are shown, even if they haven't been accessed yet: +.. doctest:: + :options: +SKIP + >>> dir(Mock()) ['assert_any_call', 'assert_called_once_with', @@ -2048,6 +2125,9 @@ filtered from the result of calling :func:`dir` on a :class:`Mock`. If you disli behaviour you can switch it off by setting the module level switch :data:`FILTER_DIR`: +.. doctest:: + :options: +SKIP + >>> from unittest import mock >>> mock.FILTER_DIR = False >>> dir(mock.Mock()) @@ -2108,6 +2188,9 @@ The issue is that even if you mock out the call to :func:`open` it is the Mocking context managers with a :class:`MagicMock` is common enough and fiddly enough that a helper function is useful. +.. doctest:: + :options: +SKIP + >>> m = mock_open() >>> with patch('__main__.open', m): ... with open('foo', 'w') as h: @@ -2124,6 +2207,9 @@ enough that a helper function is useful. And for reading files: +.. doctest:: + :options: +SKIP + >>> with patch('__main__.open', mock_open(read_data='bibble')) as m: ... with open('foo') as h: ... result = h.read() @@ -2217,6 +2303,9 @@ hit. Here's an example of it in use: +.. doctest:: + :options: +SKIP + >>> from urllib import request >>> patcher = patch('__main__.request', autospec=True) >>> mock_request = patcher.start() @@ -2237,6 +2326,9 @@ we try to call it incorrectly: The spec also applies to instantiated classes (i.e. the return value of specced mocks): +.. doctest:: + :options: +SKIP + >>> req = request.Request('foo') >>> req @@ -2245,6 +2337,9 @@ specced mocks): mocked out :class:`request.Request` is a non-callable mock. With the spec in place any typos in our asserts will raise the correct error: +.. doctest:: + :options: +SKIP + >>> req.add_header('spam', 'eggs') >>> req.add_header.assret_called_with @@ -2279,6 +2374,9 @@ created in the :meth:`__init__` method and not to exist on the class at all. *autospec* can't know about any dynamically created attributes and restricts the api to visible attributes. +.. doctest:: + :options: +SKIP + >>> class Something: ... def __init__(self): ... self.a = 33 @@ -2297,6 +2395,9 @@ attributes on the mock after creation. Just because *autospec* doesn't allow you to fetch attributes that don't exist on the spec it doesn't prevent you setting them: +.. doctest:: + :options: +SKIP + >>> with patch('__main__.Something', autospec=True): ... thing = Something() ... thing.a = 33 @@ -2307,6 +2408,9 @@ prevent you setting non-existent attributes. This is useful if you want to ensure your code only *sets* valid attributes too, but obviously it prevents this particular scenario: +.. doctest:: + :options: +SKIP + >>> with patch('__main__.Something', autospec=True, spec_set=True): ... thing = Something() ... thing.a = 33 @@ -2348,6 +2452,9 @@ production class. Both of these require you to use an alternative object as the spec. Thankfully :func:`patch` supports this - you can simply pass the alternative object as the *autospec* argument: +.. doctest:: + :options: +SKIP + >>> class Something: ... def __init__(self): ... self.a = 33