michael@0: =========================== michael@0: Getting Started with Mock michael@0: =========================== michael@0: michael@0: .. _getting-started: michael@0: michael@0: .. index:: Getting Started michael@0: michael@0: .. testsetup:: michael@0: michael@0: class SomeClass(object): michael@0: static_method = None michael@0: class_method = None michael@0: attribute = None michael@0: michael@0: sys.modules['package'] = package = Mock(name='package') michael@0: sys.modules['package.module'] = module = package.module michael@0: sys.modules['module'] = package.module michael@0: michael@0: michael@0: Using Mock michael@0: ========== michael@0: michael@0: Mock Patching Methods michael@0: --------------------- michael@0: michael@0: Common uses for :class:`Mock` objects include: michael@0: michael@0: * Patching methods michael@0: * Recording method calls on objects michael@0: 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: michael@0: .. doctest:: michael@0: michael@0: >>> real = SomeClass() michael@0: >>> real.method = MagicMock(name='method') michael@0: >>> real.method(3, 4, 5, key='value') michael@0: michael@0: 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: michael@0: .. note:: michael@0: michael@0: In most of these examples the :class:`Mock` and :class:`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: michael@0: Once the mock has been called its :attr:`~Mock.called` attribute is set to michael@0: `True`. More importantly we can use the :meth:`~Mock.assert_called_with` or michael@0: :meth:`~Mock.assert_called_once_with` method to check that it was called with michael@0: the correct arguments. michael@0: michael@0: This example tests that calling `ProductionClass().method` results in a call to michael@0: the `something` method: michael@0: michael@0: .. doctest:: michael@0: 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: michael@0: michael@0: michael@0: Mock for Method Calls on an Object michael@0: ---------------------------------- michael@0: 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: 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: michael@0: .. doctest:: michael@0: michael@0: >>> class ProductionClass(object): michael@0: ... def closer(self, something): michael@0: ... something.close() michael@0: ... 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: michael@0: .. doctest:: michael@0: michael@0: >>> real = ProductionClass() michael@0: >>> mock = Mock() michael@0: >>> real.closer(mock) michael@0: >>> mock.close.assert_called_with() michael@0: 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 :meth:`~Mock.assert_called_with` michael@0: will raise a failure exception. michael@0: michael@0: michael@0: Mocking Classes michael@0: --------------- michael@0: 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: 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 :attr:`~Mock.return_value`. michael@0: michael@0: .. doctest:: michael@0: 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: michael@0: michael@0: Naming your mocks michael@0: ----------------- michael@0: 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: michael@0: .. doctest:: michael@0: michael@0: >>> mock = MagicMock(name='foo') michael@0: >>> mock michael@0: michael@0: >>> mock.method michael@0: michael@0: michael@0: michael@0: Tracking all Calls michael@0: ------------------ michael@0: michael@0: Often you want to track more than a single call to a method. The michael@0: :attr:`~Mock.mock_calls` attribute records all calls michael@0: to child attributes of the mock - and also to their children. michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> mock = MagicMock() michael@0: >>> mock.method() michael@0: michael@0: >>> mock.attribute.method(10, x=53) michael@0: michael@0: >>> mock.mock_calls michael@0: [call.method(), call.attribute.method(10, x=53)] michael@0: 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: michael@0: You use the :data:`call` object to construct lists for comparing with michael@0: `mock_calls`: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> expected = [call.method(), call.attribute.method(10, x=53)] michael@0: >>> mock.mock_calls == expected michael@0: True michael@0: michael@0: michael@0: Setting Return Values and Attributes michael@0: ------------------------------------ michael@0: michael@0: Setting the return values on a mock object is trivially easy: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> mock = Mock() michael@0: >>> mock.return_value = 3 michael@0: >>> mock() michael@0: 3 michael@0: michael@0: Of course you can do the same for methods on the mock: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> mock = Mock() michael@0: >>> mock.method.return_value = 3 michael@0: >>> mock.method() michael@0: 3 michael@0: michael@0: The return value can also be set in the constructor: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> mock = Mock(return_value=3) michael@0: >>> mock() michael@0: 3 michael@0: michael@0: If you need an attribute setting on your mock, just do it: michael@0: michael@0: .. doctest:: michael@0: michael@0: >>> mock = Mock() michael@0: >>> mock.x = 3 michael@0: >>> mock.x michael@0: 3 michael@0: 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: michael@0: We can use :data:`call` to construct the set of calls in a "chained call" like michael@0: this for easy assertion afterwards: michael@0: michael@0: michael@0: .. doctest:: michael@0: 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: 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: michael@0: michael@0: michael@0: Raising exceptions with mocks michael@0: ----------------------------- michael@0: michael@0: A useful attribute is :attr:`~Mock.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: michael@0: .. doctest:: michael@0: 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: michael@0: michael@0: Side effect functions and iterables michael@0: ----------------------------------- michael@0: 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: michael@0: .. doctest:: michael@0: 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: michael@0: 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: michael@0: .. doctest:: michael@0: 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: michael@0: michael@0: Creating a Mock from an Existing Object michael@0: --------------------------------------- michael@0: 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: 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: michael@0: .. doctest:: michael@0: 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: 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: michael@0: michael@0: michael@0: Patch Decorators michael@0: ================ michael@0: michael@0: .. note:: michael@0: 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 :ref:`where to patch `. michael@0: michael@0: 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: 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: michael@0: `patch.object`: michael@0: michael@0: .. doctest:: michael@0: 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: michael@0: If you are patching a module (including `__builtin__`) then use `patch` michael@0: instead of `patch.object`: michael@0: michael@0: .. doctest:: michael@0: 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: michael@0: The module name can be 'dotted', in the form `package.module` if needed: michael@0: michael@0: .. doctest:: michael@0: 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: michael@0: A nice pattern is to actually decorate test methods themselves: michael@0: michael@0: .. doctest:: michael@0: 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: 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: michael@0: .. doctest:: michael@0: 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: michael@0: You can stack up multiple patch decorators using this pattern: michael@0: michael@0: .. doctest:: michael@0: 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: 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: michael@0: There is also :func:`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: michael@0: .. doctest:: michael@0: 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: michael@0: `patch`, `patch.object` and `patch.dict` can all be used as context managers. michael@0: 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: michael@0: .. doctest:: michael@0: 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: michael@0: 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: michael@0: For some more advanced examples, see the :ref:`further-examples` page.