michael@0: michael@0: michael@0: michael@0: michael@0: michael@0:
michael@0: michael@0: michael@0:Common uses for Mock objects include:
michael@0:You might want to replace a method on an object to check that michael@0: it is called with the correct arguments by another part of the system:
michael@0:>>> real = SomeClass()
michael@0: >>> real.method = MagicMock(name='method')
michael@0: >>> real.method(3, 4, 5, key='value')
michael@0: <MagicMock name='method()' id='...'>
michael@0:
Once our mock has been used (real.method in this example) it has methods michael@0: and attributes that allow you to make assertions about how it has been used.
michael@0:Note
michael@0:In most of these examples the Mock and MagicMock classes michael@0: are interchangeable. As the MagicMock is the more capable class it makes michael@0: a sensible one to use by default.
michael@0:Once the mock has been called its called attribute is set to michael@0: True. More importantly we can use the assert_called_with() or michael@0: assert_called_once_with() method to check that it was called with michael@0: the correct arguments.
michael@0:This example tests that calling ProductionClass().method results in a call to michael@0: the something method:
michael@0:>>> from mock import MagicMock
michael@0: >>> class ProductionClass(object):
michael@0: ... def method(self):
michael@0: ... self.something(1, 2, 3)
michael@0: ... def something(self, a, b, c):
michael@0: ... pass
michael@0: ...
michael@0: >>> real = ProductionClass()
michael@0: >>> real.something = MagicMock()
michael@0: >>> real.method()
michael@0: >>> real.something.assert_called_once_with(1, 2, 3)
michael@0:
In the last example we patched a method directly on an object to check that it michael@0: was called correctly. Another common use case is to pass an object into a michael@0: method (or some part of the system under test) and then check that it is used michael@0: in the correct way.
michael@0:The simple ProductionClass below has a closer method. If it is called with michael@0: an object then it calls close on it.
michael@0:>>> class ProductionClass(object):
michael@0: ... def closer(self, something):
michael@0: ... something.close()
michael@0: ...
michael@0:
So to test it we need to pass in an object with a close method and check michael@0: that it was called correctly.
michael@0:>>> real = ProductionClass()
michael@0: >>> mock = Mock()
michael@0: >>> real.closer(mock)
michael@0: >>> mock.close.assert_called_with()
michael@0:
We don’t have to do any work to provide the ‘close’ method on our mock. michael@0: Accessing close creates it. So, if ‘close’ hasn’t already been called then michael@0: accessing it in the test will create it, but assert_called_with() michael@0: will raise a failure exception.
michael@0:A common use case is to mock out classes instantiated by your code under test. michael@0: When you patch a class, then that class is replaced with a mock. Instances michael@0: are created by calling the class. This means you access the “mock instance” michael@0: by looking at the return value of the mocked class.
michael@0:In the example below we have a function some_function that instantiates Foo michael@0: and calls a method on it. The call to patch replaces the class Foo with a michael@0: mock. The Foo instance is the result of calling the mock, so it is configured michael@0: by modifying the mock return_value.
michael@0:>>> def some_function():
michael@0: ... instance = module.Foo()
michael@0: ... return instance.method()
michael@0: ...
michael@0: >>> with patch('module.Foo') as mock:
michael@0: ... instance = mock.return_value
michael@0: ... instance.method.return_value = 'the result'
michael@0: ... result = some_function()
michael@0: ... assert result == 'the result'
michael@0:
It can be useful to give your mocks a name. The name is shown in the repr of michael@0: the mock and can be helpful when the mock appears in test failure messages. The michael@0: name is also propagated to attributes or methods of the mock:
michael@0:>>> mock = MagicMock(name='foo')
michael@0: >>> mock
michael@0: <MagicMock name='foo' id='...'>
michael@0: >>> mock.method
michael@0: <MagicMock name='foo.method' id='...'>
michael@0:
Often you want to track more than a single call to a method. The michael@0: mock_calls attribute records all calls michael@0: to child attributes of the mock - and also to their children.
michael@0:>>> mock = MagicMock()
michael@0: >>> mock.method()
michael@0: <MagicMock name='mock.method()' id='...'>
michael@0: >>> mock.attribute.method(10, x=53)
michael@0: <MagicMock name='mock.attribute.method()' id='...'>
michael@0: >>> mock.mock_calls
michael@0: [call.method(), call.attribute.method(10, x=53)]
michael@0:
If you make an assertion about mock_calls and any unexpected methods michael@0: have been called, then the assertion will fail. This is useful because as well michael@0: as asserting that the calls you expected have been made, you are also checking michael@0: that they were made in the right order and with no additional calls:
michael@0:You use the call object to construct lists for comparing with michael@0: mock_calls:
michael@0:>>> expected = [call.method(), call.attribute.method(10, x=53)]
michael@0: >>> mock.mock_calls == expected
michael@0: True
michael@0:
Setting the return values on a mock object is trivially easy:
michael@0:>>> mock = Mock()
michael@0: >>> mock.return_value = 3
michael@0: >>> mock()
michael@0: 3
michael@0:
Of course you can do the same for methods on the mock:
michael@0:>>> mock = Mock()
michael@0: >>> mock.method.return_value = 3
michael@0: >>> mock.method()
michael@0: 3
michael@0:
The return value can also be set in the constructor:
michael@0:>>> mock = Mock(return_value=3)
michael@0: >>> mock()
michael@0: 3
michael@0:
If you need an attribute setting on your mock, just do it:
michael@0:>>> mock = Mock()
michael@0: >>> mock.x = 3
michael@0: >>> mock.x
michael@0: 3
michael@0:
Sometimes you want to mock up a more complex situation, like for example michael@0: mock.connection.cursor().execute(“SELECT 1”). If we wanted this call to michael@0: return a list, then we have to configure the result of the nested call.
michael@0:We can use call to construct the set of calls in a “chained call” like michael@0: this for easy assertion afterwards:
michael@0:>>> mock = Mock()
michael@0: >>> cursor = mock.connection.cursor.return_value
michael@0: >>> cursor.execute.return_value = ['foo']
michael@0: >>> mock.connection.cursor().execute("SELECT 1")
michael@0: ['foo']
michael@0: >>> expected = call.connection.cursor().execute("SELECT 1").call_list()
michael@0: >>> mock.mock_calls
michael@0: [call.connection.cursor(), call.connection.cursor().execute('SELECT 1')]
michael@0: >>> mock.mock_calls == expected
michael@0: True
michael@0:
It is the call to .call_list() that turns our call object into a list of michael@0: calls representing the chained calls.
michael@0:A useful attribute is side_effect. If you set this to an michael@0: exception class or instance then the exception will be raised when the mock michael@0: is called.
michael@0:>>> mock = Mock(side_effect=Exception('Boom!'))
michael@0: >>> mock()
michael@0: Traceback (most recent call last):
michael@0: ...
michael@0: Exception: Boom!
michael@0:
side_effect can also be set to a function or an iterable. The use case for michael@0: side_effect as an iterable is where your mock is going to be called several michael@0: times, and you want each call to return a different value. When you set michael@0: side_effect to an iterable every call to the mock returns the next value michael@0: from the iterable:
michael@0:>>> mock = MagicMock(side_effect=[4, 5, 6])
michael@0: >>> mock()
michael@0: 4
michael@0: >>> mock()
michael@0: 5
michael@0: >>> mock()
michael@0: 6
michael@0:
For more advanced use cases, like dynamically varying the return values michael@0: depending on what the mock is called with, side_effect can be a function. michael@0: The function will be called with the same arguments as the mock. Whatever the michael@0: function returns is what the call returns:
michael@0:>>> vals = {(1, 2): 1, (2, 3): 2}
michael@0: >>> def side_effect(*args):
michael@0: ... return vals[args]
michael@0: ...
michael@0: >>> mock = MagicMock(side_effect=side_effect)
michael@0: >>> mock(1, 2)
michael@0: 1
michael@0: >>> mock(2, 3)
michael@0: 2
michael@0:
One problem with over use of mocking is that it couples your tests to the michael@0: implementation of your mocks rather than your real code. Suppose you have a michael@0: class that implements some_method. In a test for another class, you michael@0: provide a mock of this object that also provides some_method. If later michael@0: you refactor the first class, so that it no longer has some_method - then michael@0: your tests will continue to pass even though your code is now broken!
michael@0:Mock allows you to provide an object as a specification for the mock, michael@0: using the spec keyword argument. Accessing methods / attributes on the michael@0: mock that don’t exist on your specification object will immediately raise an michael@0: attribute error. If you change the implementation of your specification, then michael@0: tests that use that class will start failing immediately without you having to michael@0: instantiate the class in those tests.
michael@0:>>> mock = Mock(spec=SomeClass)
michael@0: >>> mock.old_method()
michael@0: Traceback (most recent call last):
michael@0: ...
michael@0: AttributeError: object has no attribute 'old_method'
michael@0:
If you want a stronger form of specification that prevents the setting michael@0: of arbitrary attributes as well as the getting of them then you can use michael@0: spec_set instead of spec.
michael@0:Note
michael@0:With patch it matters that you patch objects in the namespace where they michael@0: are looked up. This is normally straightforward, but for a quick guide michael@0: read where to patch.
michael@0:A common need in tests is to patch a class attribute or a module attribute, michael@0: for example patching a builtin or patching a class in a module to test that it michael@0: is instantiated. Modules and classes are effectively global, so patching on michael@0: them has to be undone after the test or the patch will persist into other michael@0: tests and cause hard to diagnose problems.
michael@0:mock provides three convenient decorators for this: patch, patch.object and michael@0: patch.dict. patch takes a single string, of the form michael@0: package.module.Class.attribute to specify the attribute you are patching. It michael@0: also optionally takes a value that you want the attribute (or class or michael@0: whatever) to be replaced with. ‘patch.object’ takes an object and the name of michael@0: the attribute you would like patched, plus optionally the value to patch it michael@0: with.
michael@0:patch.object:
michael@0:>>> original = SomeClass.attribute
michael@0: >>> @patch.object(SomeClass, 'attribute', sentinel.attribute)
michael@0: ... def test():
michael@0: ... assert SomeClass.attribute == sentinel.attribute
michael@0: ...
michael@0: >>> test()
michael@0: >>> assert SomeClass.attribute == original
michael@0:
michael@0: >>> @patch('package.module.attribute', sentinel.attribute)
michael@0: ... def test():
michael@0: ... from package.module import attribute
michael@0: ... assert attribute is sentinel.attribute
michael@0: ...
michael@0: >>> test()
michael@0:
If you are patching a module (including __builtin__) then use patch michael@0: instead of patch.object:
michael@0:>>> mock = MagicMock(return_value = sentinel.file_handle)
michael@0: >>> with patch('__builtin__.open', mock):
michael@0: ... handle = open('filename', 'r')
michael@0: ...
michael@0: >>> mock.assert_called_with('filename', 'r')
michael@0: >>> assert handle == sentinel.file_handle, "incorrect file handle returned"
michael@0:
The module name can be ‘dotted’, in the form package.module if needed:
michael@0:>>> @patch('package.module.ClassName.attribute', sentinel.attribute)
michael@0: ... def test():
michael@0: ... from package.module import ClassName
michael@0: ... assert ClassName.attribute == sentinel.attribute
michael@0: ...
michael@0: >>> test()
michael@0:
A nice pattern is to actually decorate test methods themselves:
michael@0:>>> class MyTest(unittest2.TestCase):
michael@0: ... @patch.object(SomeClass, 'attribute', sentinel.attribute)
michael@0: ... def test_something(self):
michael@0: ... self.assertEqual(SomeClass.attribute, sentinel.attribute)
michael@0: ...
michael@0: >>> original = SomeClass.attribute
michael@0: >>> MyTest('test_something').test_something()
michael@0: >>> assert SomeClass.attribute == original
michael@0:
If you want to patch with a Mock, you can use patch with only one argument michael@0: (or patch.object with two arguments). The mock will be created for you and michael@0: passed into the test function / method:
michael@0:>>> class MyTest(unittest2.TestCase):
michael@0: ... @patch.object(SomeClass, 'static_method')
michael@0: ... def test_something(self, mock_method):
michael@0: ... SomeClass.static_method()
michael@0: ... mock_method.assert_called_with()
michael@0: ...
michael@0: >>> MyTest('test_something').test_something()
michael@0:
You can stack up multiple patch decorators using this pattern:
michael@0:>>> class MyTest(unittest2.TestCase):
michael@0: ... @patch('package.module.ClassName1')
michael@0: ... @patch('package.module.ClassName2')
michael@0: ... def test_something(self, MockClass2, MockClass1):
michael@0: ... self.assertTrue(package.module.ClassName1 is MockClass1)
michael@0: ... self.assertTrue(package.module.ClassName2 is MockClass2)
michael@0: ...
michael@0: >>> MyTest('test_something').test_something()
michael@0:
When you nest patch decorators the mocks are passed in to the decorated michael@0: function in the same order they applied (the normal python order that michael@0: decorators are applied). This means from the bottom up, so in the example michael@0: above the mock for test_module.ClassName2 is passed in first.
michael@0:There is also patch.dict() for setting values in a dictionary just michael@0: during a scope and restoring the dictionary to its original state when the test michael@0: ends:
michael@0:>>> foo = {'key': 'value'}
michael@0: >>> original = foo.copy()
michael@0: >>> with patch.dict(foo, {'newkey': 'newvalue'}, clear=True):
michael@0: ... assert foo == {'newkey': 'newvalue'}
michael@0: ...
michael@0: >>> assert foo == original
michael@0:
patch, patch.object and patch.dict can all be used as context managers.
michael@0:Where you use patch to create a mock for you, you can get a reference to the michael@0: mock using the “as” form of the with statement:
michael@0:>>> class ProductionClass(object):
michael@0: ... def method(self):
michael@0: ... pass
michael@0: ...
michael@0: >>> with patch.object(ProductionClass, 'method') as mock_method:
michael@0: ... mock_method.return_value = None
michael@0: ... real = ProductionClass()
michael@0: ... real.method(1, 2, 3)
michael@0: ...
michael@0: >>> mock_method.assert_called_with(1, 2, 3)
michael@0:
As an alternative patch, patch.object and patch.dict can be used as michael@0: class decorators. When used in this way it is the same as applying the michael@0: decorator indvidually to every method whose name starts with “test”.
michael@0:For some more advanced examples, see the Further Examples page.
michael@0: