summaryrefslogtreecommitdiff
path: root/python/mock-1.0.0/html/_sources/mocksignature.txt
diff options
context:
space:
mode:
Diffstat (limited to 'python/mock-1.0.0/html/_sources/mocksignature.txt')
-rw-r--r--python/mock-1.0.0/html/_sources/mocksignature.txt262
1 files changed, 262 insertions, 0 deletions
diff --git a/python/mock-1.0.0/html/_sources/mocksignature.txt b/python/mock-1.0.0/html/_sources/mocksignature.txt
new file mode 100644
index 000000000..dbb5019fb
--- /dev/null
+++ b/python/mock-1.0.0/html/_sources/mocksignature.txt
@@ -0,0 +1,262 @@
+mocksignature
+=============
+
+.. currentmodule:: mock
+
+.. note::
+
+ :ref:`auto-speccing`, added in mock 0.8, is a more advanced version of
+ `mocksignature` and can be used for many of the same use cases.
+
+A problem with using mock objects to replace real objects in your tests is that
+:class:`Mock` can be *too* flexible. Your code can treat the mock objects in
+any way and you have to manually check that they were called correctly. If your
+code calls functions or methods with the wrong number of arguments then mocks
+don't complain.
+
+The solution to this is `mocksignature`, which creates functions with the
+same signature as the original, but delegating to a mock. You can interrogate
+the mock in the usual way to check it has been called with the *right*
+arguments, but if it is called with the wrong number of arguments it will
+raise a `TypeError` in the same way your production code would.
+
+Another advantage is that your mocked objects are real functions, which can
+be useful when your code uses
+`inspect <http://docs.python.org/library/inspect.html>`_ or depends on
+functions being function objects.
+
+.. function:: mocksignature(func, mock=None, skipfirst=False)
+
+ Create a new function with the same signature as `func` that delegates
+ to `mock`. If `skipfirst` is True the first argument is skipped, useful
+ for methods where `self` needs to be omitted from the new function.
+
+ If you don't pass in a `mock` then one will be created for you.
+
+ Functions returned by `mocksignature` have many of the same attributes
+ and assert methods as a mock object.
+
+ The mock is set as the `mock` attribute of the returned function for easy
+ access.
+
+ `mocksignature` can also be used with classes. It copies the signature of
+ the `__init__` method.
+
+ When used with callable objects (instances) it copies the signature of the
+ `__call__` method.
+
+`mocksignature` will work out if it is mocking the signature of a method on
+an instance or a method on a class and do the "right thing" with the `self`
+argument in both cases.
+
+Because of a limitation in the way that arguments are collected by functions
+created by `mocksignature` they are *always* passed as positional arguments
+(including defaults) and not keyword arguments.
+
+
+mocksignature api
+-----------------
+
+Although the objects returned by `mocksignature` api are real function objects,
+they have much of the same api as the :class:`Mock` class. This includes the
+assert methods:
+
+.. doctest::
+
+ >>> def func(a, b, c):
+ ... pass
+ ...
+ >>> func2 = mocksignature(func)
+ >>> func2.called
+ False
+ >>> func2.return_value = 3
+ >>> func2(1, 2, 3)
+ 3
+ >>> func2.called
+ True
+ >>> func2.assert_called_once_with(1, 2, 3)
+ >>> func2.assert_called_with(1, 2, 4)
+ Traceback (most recent call last):
+ ...
+ AssertionError: Expected call: mock(1, 2, 4)
+ Actual call: mock(1, 2, 3)
+ >>> func2.call_count
+ 1
+ >>> func2.side_effect = IndexError
+ >>> func2(4, 5, 6)
+ Traceback (most recent call last):
+ ...
+ IndexError
+
+The mock object that is being delegated to is available as the `mock` attribute
+of the function created by `mocksignature`.
+
+.. doctest::
+
+ >>> func2.mock.mock_calls
+ [call(1, 2, 3), call(4, 5, 6)]
+
+The methods and attributes available on functions returned by `mocksignature`
+are:
+
+ :meth:`~Mock.assert_any_call`, :meth:`~Mock.assert_called_once_with`,
+ :meth:`~Mock.assert_called_with`, :meth:`~Mock.assert_has_calls`,
+ :attr:`~Mock.call_args`, :attr:`~Mock.call_args_list`,
+ :attr:`~Mock.call_count`, :attr:`~Mock.called`,
+ :attr:`~Mock.method_calls`, `mock`, :attr:`~Mock.mock_calls`,
+ :meth:`~Mock.reset_mock`, :attr:`~Mock.return_value`, and
+ :attr:`~Mock.side_effect`.
+
+
+Example use
+-----------
+
+Basic use
+~~~~~~~~~
+
+.. doctest::
+
+ >>> def function(a, b, c=None):
+ ... pass
+ ...
+ >>> mock = Mock()
+ >>> function = mocksignature(function, mock)
+ >>> function()
+ Traceback (most recent call last):
+ ...
+ TypeError: <lambda>() takes at least 2 arguments (0 given)
+ >>> function.return_value = 'some value'
+ >>> function(1, 2, 'foo')
+ 'some value'
+ >>> function.assert_called_with(1, 2, 'foo')
+
+
+Keyword arguments
+~~~~~~~~~~~~~~~~~
+
+Note that arguments to functions created by `mocksignature` are always passed
+in to the underlying mock by position even when called with keywords:
+
+.. doctest::
+
+ >>> def function(a, b, c=None):
+ ... pass
+ ...
+ >>> function = mocksignature(function)
+ >>> function.return_value = None
+ >>> function(1, 2)
+ >>> function.assert_called_with(1, 2, None)
+
+
+Mocking methods and self
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+When you use `mocksignature` to replace a method on a class then `self`
+will be included in the method signature - and you will need to include
+the instance when you do your asserts.
+
+As a curious factor of the way Python (2) wraps methods fetched from a class,
+we can *get* the `return_value` from a function set on a class, but we can't
+set it. We have to do this through the exposed `mock` attribute instead:
+
+.. doctest::
+
+ >>> class SomeClass(object):
+ ... def method(self, a, b, c=None):
+ ... pass
+ ...
+ >>> SomeClass.method = mocksignature(SomeClass.method)
+ >>> SomeClass.method.mock.return_value = None
+ >>> instance = SomeClass()
+ >>> instance.method()
+ Traceback (most recent call last):
+ ...
+ TypeError: <lambda>() takes at least 4 arguments (1 given)
+ >>> instance.method(1, 2, 3)
+ >>> instance.method.assert_called_with(instance, 1, 2, 3)
+
+When you use `mocksignature` on instance methods `self` isn't included (and we
+can set the `return_value` etc directly):
+
+.. doctest::
+
+ >>> class SomeClass(object):
+ ... def method(self, a, b, c=None):
+ ... pass
+ ...
+ >>> instance = SomeClass()
+ >>> instance.method = mocksignature(instance.method)
+ >>> instance.method.return_value = None
+ >>> instance.method(1, 2, 3)
+ >>> instance.method.assert_called_with(1, 2, 3)
+
+
+mocksignature with classes
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When used with a class `mocksignature` copies the signature of the `__init__`
+method.
+
+.. doctest::
+
+ >>> class Something(object):
+ ... def __init__(self, foo, bar):
+ ... pass
+ ...
+ >>> MockSomething = mocksignature(Something)
+ >>> instance = MockSomething(10, 9)
+ >>> assert instance is MockSomething.return_value
+ >>> MockSomething.assert_called_with(10, 9)
+ >>> MockSomething()
+ Traceback (most recent call last):
+ ...
+ TypeError: <lambda>() takes at least 2 arguments (0 given)
+
+Because the object returned by `mocksignature` is a function rather than a
+`Mock` you lose the other capabilities of `Mock`, like dynamic attribute
+creation.
+
+
+mocksignature with callable objects
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When used with a callable object `mocksignature` copies the signature of the
+`__call__` method.
+
+.. doctest::
+
+ >>> class Something(object):
+ ... def __call__(self, spam, eggs):
+ ... pass
+ ...
+ >>> something = Something()
+ >>> mock_something = mocksignature(something)
+ >>> result = mock_something(10, 9)
+ >>> mock_something.assert_called_with(10, 9)
+ >>> mock_something()
+ Traceback (most recent call last):
+ ...
+ TypeError: <lambda>() takes at least 2 arguments (0 given)
+
+
+mocksignature argument to patch
+-------------------------------
+
+`mocksignature` is available as a keyword argument to :func:`patch` or
+:func:`patch.object`. It can be used with functions / methods / classes and
+callable objects.
+
+.. doctest::
+
+ >>> class SomeClass(object):
+ ... def method(self, a, b, c=None):
+ ... pass
+ ...
+ >>> @patch.object(SomeClass, 'method', mocksignature=True)
+ ... def test(mock_method):
+ ... instance = SomeClass()
+ ... mock_method.return_value = None
+ ... instance.method(1, 2)
+ ... mock_method.assert_called_with(instance, 1, 2, None)
+ ...
+ >>> test()