michael@0: michael@0: michael@0: michael@0: michael@0: michael@0:
michael@0: michael@0: michael@0:The patch decorators are used for patching objects only within the scope of michael@0: the function they decorate. They automatically handle the unpatching for you, michael@0: even if exceptions are raised. All of these functions can also be used in with michael@0: statements or as class decorators.
michael@0:Note
michael@0:patch is straightforward to use. The key is to do the patching in the michael@0: right namespace. See the section where to patch.
michael@0:patch acts as a function decorator, class decorator or a context michael@0: manager. Inside the body of the function or with statement, the target michael@0: is patched with a new object. When the function/with statement exits michael@0: the patch is undone.
michael@0:If new is omitted, then the target is replaced with a michael@0: MagicMock. If patch is used as a decorator and new is michael@0: omitted, the created mock is passed in as an extra argument to the michael@0: decorated function. If patch is used as a context manager the created michael@0: mock is returned by the context manager.
michael@0:target should be a string in the form ‘package.module.ClassName’. The michael@0: target is imported and the specified object replaced with the new michael@0: object, so the target must be importable from the environment you are michael@0: calling patch from. The target is imported when the decorated function michael@0: is executed, not at decoration time.
michael@0:The spec and spec_set keyword arguments are passed to the MagicMock michael@0: if patch is creating one for you.
michael@0:In addition you can pass spec=True or spec_set=True, which causes michael@0: patch to pass in the object being mocked as the spec/spec_set object.
michael@0:new_callable allows you to specify a different class, or callable object, michael@0: that will be called to create the new object. By default MagicMock is michael@0: used.
michael@0:A more powerful form of spec is autospec. If you set autospec=True michael@0: then the mock with be created with a spec from the object being replaced. michael@0: All attributes of the mock will also have the spec of the corresponding michael@0: attribute of the object being replaced. Methods and functions being mocked michael@0: will have their arguments checked and will raise a TypeError if they are michael@0: called with the wrong signature. For mocks michael@0: replacing a class, their return value (the ‘instance’) will have the same michael@0: spec as the class. See the create_autospec() function and michael@0: Autospeccing.
michael@0:Instead of autospec=True you can pass autospec=some_object to use an michael@0: arbitrary object as the spec instead of the one being replaced.
michael@0:By default patch will fail to replace attributes that don’t exist. If michael@0: you pass in create=True, and the attribute doesn’t exist, patch will michael@0: create the attribute for you when the patched function is called, and michael@0: delete it again afterwards. This is useful for writing tests against michael@0: attributes that your production code creates at runtime. It is off by by michael@0: default because it can be dangerous. With it switched on you can write michael@0: passing tests against APIs that don’t actually exist!
michael@0:Patch can be used as a TestCase class decorator. It works by michael@0: decorating each test method in the class. This reduces the boilerplate michael@0: code when your test methods share a common patchings set. patch finds michael@0: tests by looking for method names that start with patch.TEST_PREFIX. michael@0: By default this is test, which matches the way unittest finds tests. michael@0: You can specify an alternative prefix by setting patch.TEST_PREFIX.
michael@0:Patch can be used as a context manager, with the with statement. Here the michael@0: patching applies to the indented block after the with statement. If you michael@0: use “as” then the patched object will be bound to the name after the michael@0: “as”; very useful if patch is creating a mock object for you.
michael@0:patch takes arbitrary keyword arguments. These will be passed to michael@0: the Mock (or new_callable) on construction.
michael@0:patch.dict(...), patch.multiple(...) and patch.object(...) are michael@0: available for alternate use-cases.
michael@0:patch as function decorator, creating the mock for you and passing it into michael@0: the decorated function:
michael@0:>>> @patch('__main__.SomeClass')
michael@0: ... def function(normal_argument, mock_class):
michael@0: ... print mock_class is SomeClass
michael@0: ...
michael@0: >>> function(None)
michael@0: True
michael@0:
Patching a class replaces the class with a MagicMock instance. If the michael@0: class is instantiated in the code under test then it will be the michael@0: return_value of the mock that will be used.
michael@0:If the class is instantiated multiple times you could use michael@0: side_effect to return a new mock each time. Alternatively you michael@0: can set the return_value to be anything you want.
michael@0:To configure return values on methods of instances on the patched class michael@0: you must do this on the return_value. For example:
michael@0:>>> class Class(object):
michael@0: ... def method(self):
michael@0: ... pass
michael@0: ...
michael@0: >>> with patch('__main__.Class') as MockClass:
michael@0: ... instance = MockClass.return_value
michael@0: ... instance.method.return_value = 'foo'
michael@0: ... assert Class() is instance
michael@0: ... assert Class().method() == 'foo'
michael@0: ...
michael@0:
If you use spec or spec_set and patch is replacing a class, then the michael@0: return value of the created mock will have the same spec.
michael@0:>>> Original = Class
michael@0: >>> patcher = patch('__main__.Class', spec=True)
michael@0: >>> MockClass = patcher.start()
michael@0: >>> instance = MockClass()
michael@0: >>> assert isinstance(instance, Original)
michael@0: >>> patcher.stop()
michael@0:
The new_callable argument is useful where you want to use an alternative michael@0: class to the default MagicMock for the created mock. For example, if michael@0: you wanted a NonCallableMock to be used:
michael@0:>>> thing = object()
michael@0: >>> with patch('__main__.thing', new_callable=NonCallableMock) as mock_thing:
michael@0: ... assert thing is mock_thing
michael@0: ... thing()
michael@0: ...
michael@0: Traceback (most recent call last):
michael@0: ...
michael@0: TypeError: 'NonCallableMock' object is not callable
michael@0:
Another use case might be to replace an object with a StringIO instance:
michael@0:>>> from StringIO import StringIO
michael@0: >>> def foo():
michael@0: ... print 'Something'
michael@0: ...
michael@0: >>> @patch('sys.stdout', new_callable=StringIO)
michael@0: ... def test(mock_stdout):
michael@0: ... foo()
michael@0: ... assert mock_stdout.getvalue() == 'Something\n'
michael@0: ...
michael@0: >>> test()
michael@0:
When patch is creating a mock for you, it is common that the first thing michael@0: you need to do is to configure the mock. Some of that configuration can be done michael@0: in the call to patch. Any arbitrary keywords you pass into the call will be michael@0: used to set attributes on the created mock:
michael@0:>>> patcher = patch('__main__.thing', first='one', second='two')
michael@0: >>> mock_thing = patcher.start()
michael@0: >>> mock_thing.first
michael@0: 'one'
michael@0: >>> mock_thing.second
michael@0: 'two'
michael@0:
As well as attributes on the created mock attributes, like the michael@0: return_value and side_effect, of child mocks can michael@0: also be configured. These aren’t syntactically valid to pass in directly as michael@0: keyword arguments, but a dictionary with these as keys can still be expanded michael@0: into a patch call using **:
michael@0:>>> config = {'method.return_value': 3, 'other.side_effect': KeyError}
michael@0: >>> patcher = patch('__main__.thing', **config)
michael@0: >>> mock_thing = patcher.start()
michael@0: >>> mock_thing.method()
michael@0: 3
michael@0: >>> mock_thing.other()
michael@0: Traceback (most recent call last):
michael@0: ...
michael@0: KeyError
michael@0:
patch the named member (attribute) on an object (target) with a mock michael@0: object.
michael@0:patch.object can be used as a decorator, class decorator or a context michael@0: manager. Arguments new, spec, create, spec_set, autospec and michael@0: new_callable have the same meaning as for patch. Like patch, michael@0: patch.object takes arbitrary keyword arguments for configuring the mock michael@0: object it creates.
michael@0:When used as a class decorator patch.object honours patch.TEST_PREFIX michael@0: for choosing which methods to wrap.
michael@0:You can either call patch.object with three arguments or two arguments. The michael@0: three argument form takes the object to be patched, the attribute name and the michael@0: object to replace the attribute with.
michael@0:When calling with the two argument form you omit the replacement object, and a michael@0: mock is created for you and passed in as an extra argument to the decorated michael@0: function:
michael@0:>>> @patch.object(SomeClass, 'class_method')
michael@0: ... def test(mock_method):
michael@0: ... SomeClass.class_method(3)
michael@0: ... mock_method.assert_called_with(3)
michael@0: ...
michael@0: >>> test()
michael@0:
spec, create and the other arguments to patch.object have the same michael@0: meaning as they do for patch.
michael@0:Patch a dictionary, or dictionary like object, and restore the dictionary michael@0: to its original state after the test.
michael@0:in_dict can be a dictionary or a mapping like container. If it is a michael@0: mapping then it must at least support getting, setting and deleting items michael@0: plus iterating over keys.
michael@0:in_dict can also be a string specifying the name of the dictionary, which michael@0: will then be fetched by importing it.
michael@0:values can be a dictionary of values to set in the dictionary. values michael@0: can also be an iterable of (key, value) pairs.
michael@0:If clear is True then the dictionary will be cleared before the new michael@0: values are set.
michael@0:patch.dict can also be called with arbitrary keyword arguments to set michael@0: values in the dictionary.
michael@0:patch.dict can be used as a context manager, decorator or class michael@0: decorator. When used as a class decorator patch.dict honours michael@0: patch.TEST_PREFIX for choosing which methods to wrap.
michael@0:patch.dict can be used to add members to a dictionary, or simply let a test michael@0: change a dictionary, and ensure the dictionary is restored when the test michael@0: ends.
michael@0:>>> from mock import patch
michael@0: >>> foo = {}
michael@0: >>> with patch.dict(foo, {'newkey': 'newvalue'}):
michael@0: ... assert foo == {'newkey': 'newvalue'}
michael@0: ...
michael@0: >>> assert foo == {}
michael@0:
michael@0: >>> import os
michael@0: >>> with patch.dict('os.environ', {'newkey': 'newvalue'}):
michael@0: ... print os.environ['newkey']
michael@0: ...
michael@0: newvalue
michael@0: >>> assert 'newkey' not in os.environ
michael@0:
Keywords can be used in the patch.dict call to set values in the dictionary:
michael@0:>>> mymodule = MagicMock()
michael@0: >>> mymodule.function.return_value = 'fish'
michael@0: >>> with patch.dict('sys.modules', mymodule=mymodule):
michael@0: ... import mymodule
michael@0: ... mymodule.function('some', 'args')
michael@0: ...
michael@0: 'fish'
michael@0:
patch.dict can be used with dictionary like objects that aren’t actually michael@0: dictionaries. At the very minimum they must support item getting, setting, michael@0: deleting and either iteration or membership test. This corresponds to the michael@0: magic methods __getitem__, __setitem__, __delitem__ and either michael@0: __iter__ or __contains__.
michael@0:>>> class Container(object):
michael@0: ... def __init__(self):
michael@0: ... self.values = {}
michael@0: ... def __getitem__(self, name):
michael@0: ... return self.values[name]
michael@0: ... def __setitem__(self, name, value):
michael@0: ... self.values[name] = value
michael@0: ... def __delitem__(self, name):
michael@0: ... del self.values[name]
michael@0: ... def __iter__(self):
michael@0: ... return iter(self.values)
michael@0: ...
michael@0: >>> thing = Container()
michael@0: >>> thing['one'] = 1
michael@0: >>> with patch.dict(thing, one=2, two=3):
michael@0: ... assert thing['one'] == 2
michael@0: ... assert thing['two'] == 3
michael@0: ...
michael@0: >>> assert thing['one'] == 1
michael@0: >>> assert list(thing) == ['one']
michael@0:
Perform multiple patches in a single call. It takes the object to be michael@0: patched (either as an object or a string to fetch the object by importing) michael@0: and keyword arguments for the patches:
michael@0:with patch.multiple(settings, FIRST_PATCH='one', SECOND_PATCH='two'):
michael@0: ...
michael@0:
Use DEFAULT as the value if you want patch.multiple to create michael@0: mocks for you. In this case the created mocks are passed into a decorated michael@0: function by keyword, and a dictionary is returned when patch.multiple is michael@0: used as a context manager.
michael@0:patch.multiple can be used as a decorator, class decorator or a context michael@0: manager. The arguments spec, spec_set, create, autospec and michael@0: new_callable have the same meaning as for patch. These arguments will michael@0: be applied to all patches done by patch.multiple.
michael@0:When used as a class decorator patch.multiple honours patch.TEST_PREFIX michael@0: for choosing which methods to wrap.
michael@0:If you want patch.multiple to create mocks for you, then you can use michael@0: DEFAULT as the value. If you use patch.multiple as a decorator michael@0: then the created mocks are passed into the decorated function by keyword.
michael@0:>>> thing = object()
michael@0: >>> other = object()
michael@0:
michael@0: >>> @patch.multiple('__main__', thing=DEFAULT, other=DEFAULT)
michael@0: ... def test_function(thing, other):
michael@0: ... assert isinstance(thing, MagicMock)
michael@0: ... assert isinstance(other, MagicMock)
michael@0: ...
michael@0: >>> test_function()
michael@0:
patch.multiple can be nested with other patch decorators, but put arguments michael@0: passed by keyword after any of the standard arguments created by patch:
michael@0:>>> @patch('sys.exit')
michael@0: ... @patch.multiple('__main__', thing=DEFAULT, other=DEFAULT)
michael@0: ... def test_function(mock_exit, other, thing):
michael@0: ... assert 'other' in repr(other)
michael@0: ... assert 'thing' in repr(thing)
michael@0: ... assert 'exit' in repr(mock_exit)
michael@0: ...
michael@0: >>> test_function()
michael@0:
If patch.multiple is used as a context manager, the value returned by the michael@0: context manger is a dictionary where created mocks are keyed by name:
michael@0:>>> with patch.multiple('__main__', thing=DEFAULT, other=DEFAULT) as values:
michael@0: ... assert 'other' in repr(values['other'])
michael@0: ... assert 'thing' in repr(values['thing'])
michael@0: ... assert values['thing'] is thing
michael@0: ... assert values['other'] is other
michael@0: ...
michael@0:
All the patchers have start and stop methods. These make it simpler to do michael@0: patching in setUp methods or where you want to do multiple patches without michael@0: nesting decorators or with statements.
michael@0:To use them call patch, patch.object or patch.dict as normal and keep a michael@0: reference to the returned patcher object. You can then call start to put michael@0: the patch in place and stop to undo it.
michael@0:If you are using patch to create a mock for you then it will be returned by michael@0: the call to patcher.start.
michael@0:>>> patcher = patch('package.module.ClassName')
michael@0: >>> from package import module
michael@0: >>> original = module.ClassName
michael@0: >>> new_mock = patcher.start()
michael@0: >>> assert module.ClassName is not original
michael@0: >>> assert module.ClassName is new_mock
michael@0: >>> patcher.stop()
michael@0: >>> assert module.ClassName is original
michael@0: >>> assert module.ClassName is not new_mock
michael@0:
A typical use case for this might be for doing multiple patches in the setUp michael@0: method of a TestCase:
michael@0:>>> class MyTest(TestCase):
michael@0: ... def setUp(self):
michael@0: ... self.patcher1 = patch('package.module.Class1')
michael@0: ... self.patcher2 = patch('package.module.Class2')
michael@0: ... self.MockClass1 = self.patcher1.start()
michael@0: ... self.MockClass2 = self.patcher2.start()
michael@0: ...
michael@0: ... def tearDown(self):
michael@0: ... self.patcher1.stop()
michael@0: ... self.patcher2.stop()
michael@0: ...
michael@0: ... def test_something(self):
michael@0: ... assert package.module.Class1 is self.MockClass1
michael@0: ... assert package.module.Class2 is self.MockClass2
michael@0: ...
michael@0: >>> MyTest('test_something').run()
michael@0:
Caution
michael@0:If you use this technique you must ensure that the patching is “undone” by michael@0: calling stop. This can be fiddlier than you might think, because if an michael@0: exception is raised in the setUp then tearDown is not called. unittest2 cleanup functions make this michael@0: easier.
michael@0:>>> class MyTest(TestCase):
michael@0: ... def setUp(self):
michael@0: ... patcher = patch('package.module.Class')
michael@0: ... self.MockClass = patcher.start()
michael@0: ... self.addCleanup(patcher.stop)
michael@0: ...
michael@0: ... def test_something(self):
michael@0: ... assert package.module.Class is self.MockClass
michael@0: ...
michael@0: >>> MyTest('test_something').run()
michael@0:
As an added bonus you no longer need to keep a reference to the patcher michael@0: object.
michael@0:It is also possible to stop all patches which have been started by using michael@0: patch.stopall.
michael@0:Stop all active patches. Only stops patches started with start.
michael@0:All of the patchers can be used as class decorators. When used in this way michael@0: they wrap every test method on the class. The patchers recognise methods that michael@0: start with test as being test methods. This is the same way that the michael@0: unittest.TestLoader finds test methods by default.
michael@0:It is possible that you want to use a different prefix for your tests. You can michael@0: inform the patchers of the different prefix by setting patch.TEST_PREFIX:
michael@0:>>> patch.TEST_PREFIX = 'foo'
michael@0: >>> value = 3
michael@0: >>>
michael@0: >>> @patch('__main__.value', 'not three')
michael@0: ... class Thing(object):
michael@0: ... def foo_one(self):
michael@0: ... print value
michael@0: ... def foo_two(self):
michael@0: ... print value
michael@0: ...
michael@0: >>>
michael@0: >>> Thing().foo_one()
michael@0: not three
michael@0: >>> Thing().foo_two()
michael@0: not three
michael@0: >>> value
michael@0: 3
michael@0:
If you want to perform multiple patches then you can simply stack up the michael@0: decorators.
michael@0:You can stack up multiple patch decorators using this pattern:
michael@0:>>> @patch.object(SomeClass, 'class_method')
michael@0: ... @patch.object(SomeClass, 'static_method')
michael@0: ... def test(mock1, mock2):
michael@0: ... assert SomeClass.static_method is mock1
michael@0: ... assert SomeClass.class_method is mock2
michael@0: ... SomeClass.static_method('foo')
michael@0: ... SomeClass.class_method('bar')
michael@0: ... return mock1, mock2
michael@0: ...
michael@0: >>> mock1, mock2 = test()
michael@0: >>> mock1.assert_called_once_with('foo')
michael@0: >>> mock2.assert_called_once_with('bar')
michael@0:
Note that the decorators are applied from the bottom upwards. This is the michael@0: standard way that Python applies decorators. The order of the created mocks michael@0: passed into your test function matches this order.
michael@0:Like all context-managers patches can be nested using contextlib’s nested michael@0: function; every patching will appear in the tuple after “as”:
michael@0:>>> from contextlib import nested
michael@0: >>> with nested(
michael@0: ... patch('package.module.ClassName1'),
michael@0: ... patch('package.module.ClassName2')
michael@0: ... ) as (MockClass1, MockClass2):
michael@0: ... assert package.module.ClassName1 is MockClass1
michael@0: ... assert package.module.ClassName2 is MockClass2
michael@0: ...
michael@0:
patch works by (temporarily) changing the object that a name points to with michael@0: another one. There can be many names pointing to any individual object, so michael@0: for patching to work you must ensure that you patch the name used by the system michael@0: under test.
michael@0:The basic principle is that you patch where an object is looked up, which michael@0: is not necessarily the same place as where it is defined. A couple of michael@0: examples will help to clarify this.
michael@0:Imagine we have a project that we want to test with the following structure:
michael@0:a.py
michael@0: -> Defines SomeClass
michael@0:
michael@0: b.py
michael@0: -> from a import SomeClass
michael@0: -> some_function instantiates SomeClass
michael@0: Now we want to test some_function but we want to mock out SomeClass using michael@0: patch. The problem is that when we import module b, which we will have to michael@0: do then it imports SomeClass from module a. If we use patch to mock out michael@0: a.SomeClass then it will have no effect on our test; module b already has a michael@0: reference to the real SomeClass and it looks like our patching had no michael@0: effect.
michael@0:The key is to patch out SomeClass where it is used (or where it is looked up michael@0: ). In this case some_function will actually look up SomeClass in module b, michael@0: where we have imported it. The patching should look like:
michael@0:michael@0:michael@0:@patch(‘b.SomeClass’)
However, consider the alternative scenario where instead of from a import michael@0: SomeClass module b does import a and some_function uses a.SomeClass. Both michael@0: of these import forms are common. In this case the class we want to patch is michael@0: being looked up on the a module and so we have to patch a.SomeClass instead:
michael@0:michael@0:michael@0:@patch(‘a.SomeClass’)
Since version 0.6.0 both patch and patch.object have been able to correctly michael@0: patch and restore descriptors: class methods, static methods and properties. michael@0: You should patch these on the class rather than an instance.
michael@0:Since version 0.7.0 patch and patch.object work correctly with some objects michael@0: that proxy attribute access, like the django setttings object.
michael@0:Note
michael@0:In django import settings and from django.conf import settings michael@0: return different objects. If you are using libraries / apps that do both you michael@0: may have to patch both. Grrr...
michael@0: