michael@0: ========= michael@0: Helpers michael@0: ========= michael@0: michael@0: .. currentmodule:: mock michael@0: michael@0: .. testsetup:: michael@0: michael@0: mock.FILTER_DIR = True michael@0: from pprint import pprint as pp michael@0: original_dir = dir michael@0: def dir(obj): michael@0: print pp(original_dir(obj)) michael@0: michael@0: import urllib2 michael@0: __main__.urllib2 = urllib2 michael@0: michael@0: .. testcleanup:: michael@0: michael@0: dir = original_dir michael@0: mock.FILTER_DIR = True michael@0: michael@0: michael@0: michael@0: call michael@0: ==== michael@0: michael@0: .. function:: call(*args, **kwargs) michael@0: michael@0: `call` is a helper object for making simpler assertions, for comparing michael@0: with :attr:`~Mock.call_args`, :attr:`~Mock.call_args_list`, michael@0: :attr:`~Mock.mock_calls` and :attr: `~Mock.method_calls`. `call` can also be michael@0: used with :meth:`~Mock.assert_has_calls`. michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> m = MagicMock(return_value=None) michael@0: >>> m(1, 2, a='foo', b='bar') michael@0: >>> m() michael@0: >>> m.call_args_list == [call(1, 2, a='foo', b='bar'), call()] michael@0: True michael@0: michael@0: .. method:: call.call_list() michael@0: michael@0: For a call object that represents multiple calls, `call_list` michael@0: returns a list of all the intermediate calls as well as the michael@0: final call. michael@0: michael@0: `call_list` is particularly useful for making assertions on "chained calls". A michael@0: chained call is multiple calls on a single line of code. This results in michael@0: multiple entries in :attr:`~Mock.mock_calls` on a mock. Manually constructing michael@0: the sequence of calls can be tedious. michael@0: michael@0: :meth:`~call.call_list` can construct the sequence of calls from the same michael@0: chained call: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> m = MagicMock() michael@0: >>> m(1).method(arg='foo').other('bar')(2.0) michael@0: michael@0: >>> kall = call(1).method(arg='foo').other('bar')(2.0) michael@0: >>> kall.call_list() michael@0: [call(1), michael@0: call().method(arg='foo'), michael@0: call().method().other('bar'), michael@0: call().method().other()(2.0)] michael@0: >>> m.mock_calls == kall.call_list() michael@0: True michael@0: michael@0: .. _calls-as-tuples: michael@0: michael@0: A `call` object is either a tuple of (positional args, keyword args) or michael@0: (name, positional args, keyword args) depending on how it was constructed. When michael@0: you construct them yourself this isn't particularly interesting, but the `call` michael@0: objects that are in the :attr:`Mock.call_args`, :attr:`Mock.call_args_list` and michael@0: :attr:`Mock.mock_calls` attributes can be introspected to get at the individual michael@0: arguments they contain. michael@0: michael@0: The `call` objects in :attr:`Mock.call_args` and :attr:`Mock.call_args_list` michael@0: are two-tuples of (positional args, keyword args) whereas the `call` objects michael@0: in :attr:`Mock.mock_calls`, along with ones you construct yourself, are michael@0: three-tuples of (name, positional args, keyword args). michael@0: michael@0: You can use their "tupleness" to pull out the individual arguments for more michael@0: complex introspection and assertions. The positional arguments are a tuple michael@0: (an empty tuple if there are no positional arguments) and the keyword michael@0: arguments are a dictionary: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> m = MagicMock(return_value=None) michael@0: >>> m(1, 2, 3, arg='one', arg2='two') michael@0: >>> kall = m.call_args michael@0: >>> args, kwargs = kall michael@0: >>> args michael@0: (1, 2, 3) michael@0: >>> kwargs michael@0: {'arg2': 'two', 'arg': 'one'} michael@0: >>> args is kall[0] michael@0: True michael@0: >>> kwargs is kall[1] michael@0: True michael@0: michael@0: >>> m = MagicMock() michael@0: >>> m.foo(4, 5, 6, arg='two', arg2='three') michael@0: michael@0: >>> kall = m.mock_calls[0] michael@0: >>> name, args, kwargs = kall michael@0: >>> name michael@0: 'foo' michael@0: >>> args michael@0: (4, 5, 6) michael@0: >>> kwargs michael@0: {'arg2': 'three', 'arg': 'two'} michael@0: >>> name is m.mock_calls[0][0] michael@0: True michael@0: michael@0: michael@0: create_autospec michael@0: =============== michael@0: michael@0: .. function:: create_autospec(spec, spec_set=False, instance=False, **kwargs) michael@0: michael@0: Create a mock object using another object as a spec. Attributes on the michael@0: mock will use the corresponding attribute on the `spec` object as their michael@0: spec. michael@0: michael@0: Functions or methods being mocked will have their arguments checked to michael@0: ensure that they are called with the correct signature. michael@0: michael@0: If `spec_set` is `True` then attempting to set attributes that don't exist michael@0: on the spec object will raise an `AttributeError`. michael@0: michael@0: If a class is used as a spec then the return value of the mock (the michael@0: instance of the class) will have the same spec. You can use a class as the michael@0: spec for an instance object by passing `instance=True`. The returned mock michael@0: will only be callable if instances of the mock are callable. michael@0: michael@0: `create_autospec` also takes arbitrary keyword arguments that are passed to michael@0: the constructor of the created mock. michael@0: michael@0: See :ref:`auto-speccing` for examples of how to use auto-speccing with michael@0: `create_autospec` and the `autospec` argument to :func:`patch`. michael@0: michael@0: michael@0: ANY michael@0: === michael@0: michael@0: .. data:: ANY michael@0: michael@0: Sometimes you may need to make assertions about *some* of the arguments in a michael@0: call to mock, but either not care about some of the arguments or want to pull michael@0: them individually out of :attr:`~Mock.call_args` and make more complex michael@0: assertions on them. michael@0: michael@0: To ignore certain arguments you can pass in objects that compare equal to michael@0: *everything*. Calls to :meth:`~Mock.assert_called_with` and michael@0: :meth:`~Mock.assert_called_once_with` will then succeed no matter what was michael@0: passed in. michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> mock = Mock(return_value=None) michael@0: >>> mock('foo', bar=object()) michael@0: >>> mock.assert_called_once_with('foo', bar=ANY) michael@0: michael@0: `ANY` can also be used in comparisons with call lists like michael@0: :attr:`~Mock.mock_calls`: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> m = MagicMock(return_value=None) michael@0: >>> m(1) michael@0: >>> m(1, 2) michael@0: >>> m(object()) michael@0: >>> m.mock_calls == [call(1), call(1, 2), ANY] michael@0: True michael@0: michael@0: michael@0: michael@0: FILTER_DIR michael@0: ========== michael@0: michael@0: .. data:: FILTER_DIR michael@0: michael@0: `FILTER_DIR` is a module level variable that controls the way mock objects michael@0: respond to `dir` (only for Python 2.6 or more recent). The default is `True`, michael@0: which uses the filtering described below, to only show useful members. If you michael@0: dislike this filtering, or need to switch it off for diagnostic purposes, then michael@0: set `mock.FILTER_DIR = False`. michael@0: michael@0: With filtering on, `dir(some_mock)` shows only useful attributes and will michael@0: include any dynamically created attributes that wouldn't normally be shown. michael@0: If the mock was created with a `spec` (or `autospec` of course) then all the michael@0: attributes from the original are shown, even if they haven't been accessed michael@0: yet: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> dir(Mock()) michael@0: ['assert_any_call', michael@0: 'assert_called_once_with', michael@0: 'assert_called_with', michael@0: 'assert_has_calls', michael@0: 'attach_mock', michael@0: ... michael@0: >>> import urllib2 michael@0: >>> dir(Mock(spec=urllib2)) michael@0: ['AbstractBasicAuthHandler', michael@0: 'AbstractDigestAuthHandler', michael@0: 'AbstractHTTPHandler', michael@0: 'BaseHandler', michael@0: ... michael@0: michael@0: Many of the not-very-useful (private to `Mock` rather than the thing being michael@0: mocked) underscore and double underscore prefixed attributes have been michael@0: filtered from the result of calling `dir` on a `Mock`. If you dislike this michael@0: behaviour you can switch it off by setting the module level switch michael@0: `FILTER_DIR`: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> import mock michael@0: >>> mock.FILTER_DIR = False michael@0: >>> dir(mock.Mock()) michael@0: ['_NonCallableMock__get_return_value', michael@0: '_NonCallableMock__get_side_effect', michael@0: '_NonCallableMock__return_value_doc', michael@0: '_NonCallableMock__set_return_value', michael@0: '_NonCallableMock__set_side_effect', michael@0: '__call__', michael@0: '__class__', michael@0: ... michael@0: michael@0: Alternatively you can just use `vars(my_mock)` (instance members) and michael@0: `dir(type(my_mock))` (type members) to bypass the filtering irrespective of michael@0: `mock.FILTER_DIR`. michael@0: michael@0: michael@0: mock_open michael@0: ========= michael@0: michael@0: .. function:: mock_open(mock=None, read_data=None) michael@0: michael@0: A helper function to create a mock to replace the use of `open`. It works michael@0: for `open` called directly or used as a context manager. michael@0: michael@0: The `mock` argument is the mock object to configure. If `None` (the michael@0: default) then a `MagicMock` will be created for you, with the API limited michael@0: to methods or attributes available on standard file handles. michael@0: michael@0: `read_data` is a string for the `read` method of the file handle to return. michael@0: This is an empty string by default. michael@0: michael@0: Using `open` as a context manager is a great way to ensure your file handles michael@0: are closed properly and is becoming common:: michael@0: michael@0: with open('/some/path', 'w') as f: michael@0: f.write('something') michael@0: michael@0: The issue is that even if you mock out the call to `open` it is the michael@0: *returned object* that is used as a context manager (and has `__enter__` and michael@0: `__exit__` called). michael@0: michael@0: Mocking context managers with a :class:`MagicMock` is common enough and fiddly michael@0: enough that a helper function is useful. michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> from mock import mock_open michael@0: >>> m = mock_open() michael@0: >>> with patch('__main__.open', m, create=True): michael@0: ... with open('foo', 'w') as h: michael@0: ... h.write('some stuff') michael@0: ... michael@0: >>> m.mock_calls michael@0: [call('foo', 'w'), michael@0: call().__enter__(), michael@0: call().write('some stuff'), michael@0: call().__exit__(None, None, None)] michael@0: >>> m.assert_called_once_with('foo', 'w') michael@0: >>> handle = m() michael@0: >>> handle.write.assert_called_once_with('some stuff') michael@0: michael@0: And for reading files: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> with patch('__main__.open', mock_open(read_data='bibble'), create=True) as m: michael@0: ... with open('foo') as h: michael@0: ... result = h.read() michael@0: ... michael@0: >>> m.assert_called_once_with('foo') michael@0: >>> assert result == 'bibble' michael@0: michael@0: michael@0: .. _auto-speccing: michael@0: michael@0: Autospeccing michael@0: ============ michael@0: michael@0: Autospeccing is based on the existing `spec` feature of mock. It limits the michael@0: api of mocks to the api of an original object (the spec), but it is recursive michael@0: (implemented lazily) so that attributes of mocks only have the same api as michael@0: the attributes of the spec. In addition mocked functions / methods have the michael@0: same call signature as the original so they raise a `TypeError` if they are michael@0: called incorrectly. michael@0: michael@0: Before I explain how auto-speccing works, here's why it is needed. michael@0: michael@0: `Mock` is a very powerful and flexible object, but it suffers from two flaws michael@0: when used to mock out objects from a system under test. One of these flaws is michael@0: specific to the `Mock` api and the other is a more general problem with using michael@0: mock objects. michael@0: michael@0: First the problem specific to `Mock`. `Mock` has two assert methods that are michael@0: extremely handy: :meth:`~Mock.assert_called_with` and michael@0: :meth:`~Mock.assert_called_once_with`. michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> mock = Mock(name='Thing', return_value=None) michael@0: >>> mock(1, 2, 3) michael@0: >>> mock.assert_called_once_with(1, 2, 3) michael@0: >>> mock(1, 2, 3) michael@0: >>> mock.assert_called_once_with(1, 2, 3) michael@0: Traceback (most recent call last): michael@0: ... michael@0: AssertionError: Expected to be called once. Called 2 times. michael@0: michael@0: Because mocks auto-create attributes on demand, and allow you to call them michael@0: with arbitrary arguments, if you misspell one of these assert methods then michael@0: your assertion is gone: michael@0: michael@0: .. code-block:: pycon michael@0: michael@0: >>> mock = Mock(name='Thing', return_value=None) michael@0: >>> mock(1, 2, 3) michael@0: >>> mock.assret_called_once_with(4, 5, 6) michael@0: michael@0: Your tests can pass silently and incorrectly because of the typo. michael@0: michael@0: The second issue is more general to mocking. If you refactor some of your michael@0: code, rename members and so on, any tests for code that is still using the michael@0: *old api* but uses mocks instead of the real objects will still pass. This michael@0: means your tests can all pass even though your code is broken. michael@0: michael@0: Note that this is another reason why you need integration tests as well as michael@0: unit tests. Testing everything in isolation is all fine and dandy, but if you michael@0: don't test how your units are "wired together" there is still lots of room michael@0: for bugs that tests might have caught. michael@0: michael@0: `mock` already provides a feature to help with this, called speccing. If you michael@0: use a class or instance as the `spec` for a mock then you can only access michael@0: attributes on the mock that exist on the real class: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> import urllib2 michael@0: >>> mock = Mock(spec=urllib2.Request) michael@0: >>> mock.assret_called_with michael@0: Traceback (most recent call last): michael@0: ... michael@0: AttributeError: Mock object has no attribute 'assret_called_with' michael@0: michael@0: The spec only applies to the mock itself, so we still have the same issue michael@0: with any methods on the mock: michael@0: michael@0: .. code-block:: pycon michael@0: michael@0: >>> mock.has_data() michael@0: michael@0: >>> mock.has_data.assret_called_with() michael@0: michael@0: Auto-speccing solves this problem. You can either pass `autospec=True` to michael@0: `patch` / `patch.object` or use the `create_autospec` function to create a michael@0: mock with a spec. If you use the `autospec=True` argument to `patch` then the michael@0: object that is being replaced will be used as the spec object. Because the michael@0: speccing is done "lazily" (the spec is created as attributes on the mock are michael@0: accessed) you can use it with very complex or deeply nested objects (like michael@0: modules that import modules that import modules) without a big performance michael@0: hit. michael@0: michael@0: Here's an example of it in use: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> import urllib2 michael@0: >>> patcher = patch('__main__.urllib2', autospec=True) michael@0: >>> mock_urllib2 = patcher.start() michael@0: >>> urllib2 is mock_urllib2 michael@0: True michael@0: >>> urllib2.Request michael@0: michael@0: michael@0: You can see that `urllib2.Request` has a spec. `urllib2.Request` takes two michael@0: arguments in the constructor (one of which is `self`). Here's what happens if michael@0: we try to call it incorrectly: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> req = urllib2.Request() michael@0: Traceback (most recent call last): michael@0: ... michael@0: TypeError: () takes at least 2 arguments (1 given) michael@0: michael@0: The spec also applies to instantiated classes (i.e. the return value of michael@0: specced mocks): michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> req = urllib2.Request('foo') michael@0: >>> req michael@0: michael@0: michael@0: `Request` objects are not callable, so the return value of instantiating our michael@0: mocked out `urllib2.Request` is a non-callable mock. With the spec in place michael@0: any typos in our asserts will raise the correct error: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> req.add_header('spam', 'eggs') michael@0: michael@0: >>> req.add_header.assret_called_with michael@0: Traceback (most recent call last): michael@0: ... michael@0: AttributeError: Mock object has no attribute 'assret_called_with' michael@0: >>> req.add_header.assert_called_with('spam', 'eggs') michael@0: michael@0: In many cases you will just be able to add `autospec=True` to your existing michael@0: `patch` calls and then be protected against bugs due to typos and api michael@0: changes. michael@0: michael@0: As well as using `autospec` through `patch` there is a michael@0: :func:`create_autospec` for creating autospecced mocks directly: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> import urllib2 michael@0: >>> mock_urllib2 = create_autospec(urllib2) michael@0: >>> mock_urllib2.Request('foo', 'bar') michael@0: michael@0: michael@0: This isn't without caveats and limitations however, which is why it is not michael@0: the default behaviour. In order to know what attributes are available on the michael@0: spec object, autospec has to introspect (access attributes) the spec. As you michael@0: traverse attributes on the mock a corresponding traversal of the original michael@0: object is happening under the hood. If any of your specced objects have michael@0: properties or descriptors that can trigger code execution then you may not be michael@0: able to use autospec. On the other hand it is much better to design your michael@0: objects so that introspection is safe [#]_. michael@0: michael@0: A more serious problem is that it is common for instance attributes to be michael@0: created in the `__init__` method and not to exist on the class at all. michael@0: `autospec` can't know about any dynamically created attributes and restricts michael@0: the api to visible attributes. michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> class Something(object): michael@0: ... def __init__(self): michael@0: ... self.a = 33 michael@0: ... michael@0: >>> with patch('__main__.Something', autospec=True): michael@0: ... thing = Something() michael@0: ... thing.a michael@0: ... michael@0: Traceback (most recent call last): michael@0: ... michael@0: AttributeError: Mock object has no attribute 'a' michael@0: michael@0: There are a few different ways of resolving this problem. The easiest, but michael@0: not necessarily the least annoying, way is to simply set the required michael@0: attributes on the mock after creation. Just because `autospec` doesn't allow michael@0: you to fetch attributes that don't exist on the spec it doesn't prevent you michael@0: setting them: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> with patch('__main__.Something', autospec=True): michael@0: ... thing = Something() michael@0: ... thing.a = 33 michael@0: ... michael@0: michael@0: There is a more aggressive version of both `spec` and `autospec` that *does* michael@0: prevent you setting non-existent attributes. This is useful if you want to michael@0: ensure your code only *sets* valid attributes too, but obviously it prevents michael@0: this particular scenario: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> with patch('__main__.Something', autospec=True, spec_set=True): michael@0: ... thing = Something() michael@0: ... thing.a = 33 michael@0: ... michael@0: Traceback (most recent call last): michael@0: ... michael@0: AttributeError: Mock object has no attribute 'a' michael@0: michael@0: Probably the best way of solving the problem is to add class attributes as michael@0: default values for instance members initialised in `__init__`. Note that if michael@0: you are only setting default attributes in `__init__` then providing them via michael@0: class attributes (shared between instances of course) is faster too. e.g. michael@0: michael@0: .. code-block:: python michael@0: michael@0: class Something(object): michael@0: a = 33 michael@0: michael@0: This brings up another issue. It is relatively common to provide a default michael@0: value of `None` for members that will later be an object of a different type. michael@0: `None` would be useless as a spec because it wouldn't let you access *any* michael@0: attributes or methods on it. As `None` is *never* going to be useful as a michael@0: spec, and probably indicates a member that will normally of some other type, michael@0: `autospec` doesn't use a spec for members that are set to `None`. These will michael@0: just be ordinary mocks (well - `MagicMocks`): michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> class Something(object): michael@0: ... member = None michael@0: ... michael@0: >>> mock = create_autospec(Something) michael@0: >>> mock.member.foo.bar.baz() michael@0: michael@0: michael@0: If modifying your production classes to add defaults isn't to your liking michael@0: then there are more options. One of these is simply to use an instance as the michael@0: spec rather than the class. The other is to create a subclass of the michael@0: production class and add the defaults to the subclass without affecting the michael@0: production class. Both of these require you to use an alternative object as michael@0: the spec. Thankfully `patch` supports this - you can simply pass the michael@0: alternative object as the `autospec` argument: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> class Something(object): michael@0: ... def __init__(self): michael@0: ... self.a = 33 michael@0: ... michael@0: >>> class SomethingForTest(Something): michael@0: ... a = 33 michael@0: ... michael@0: >>> p = patch('__main__.Something', autospec=SomethingForTest) michael@0: >>> mock = p.start() michael@0: >>> mock.a michael@0: michael@0: michael@0: .. note:: michael@0: michael@0: An additional limitation (currently) with `autospec` is that unbound michael@0: methods on mocked classes *don't* take an "explicit self" as the first michael@0: argument - so this usage will fail with `autospec`. michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> class Foo(object): michael@0: ... def foo(self): michael@0: ... pass michael@0: ... michael@0: >>> Foo.foo(Foo()) michael@0: >>> MockFoo = create_autospec(Foo) michael@0: >>> MockFoo.foo(MockFoo()) michael@0: Traceback (most recent call last): michael@0: ... michael@0: TypeError: () takes exactly 1 argument (2 given) michael@0: michael@0: The reason is that its very hard to tell the difference between functions, michael@0: unbound methods and staticmethods across Python 2 & 3 and the alternative michael@0: implementations. This restriction may be fixed in future versions. michael@0: michael@0: michael@0: ------ michael@0: michael@0: .. [#] This only applies to classes or already instantiated objects. Calling michael@0: a mocked class to create a mock instance *does not* create a real instance. michael@0: It is only attribute lookups - along with calls to `dir` - that are done. A michael@0: way round this problem would have been to use `getattr_static michael@0: `_, michael@0: which can fetch attributes without triggering code execution. Descriptors michael@0: like `classmethod` and `staticmethod` *need* to be fetched correctly though, michael@0: so that their signatures can be mocked correctly.