unittest.mock --- Mock object library

3.3 New features.

Source code: Lib/unittest/mock.py


unittest.mock is a Python library for testing. It allows using mock objects to replace parts of the system under test and making assertions about how these parts are used.

unittest.mock provides the Mock class, which can simulate a large number of methods in the entire test suite . Once created, it is possible to assert which methods/properties were called and their parameters. You can also specify the return value and set the required properties in the usual way.

In addition, mock also provides patch() decorators for patching module and class-level properties within the test scope, and for A sentinel that creates unique objects. Read the cases in quick guide to learn how to use Mock , . patch() and MagicMock

mock is designed to be used with unittest and it is based on the 'action -> assertion' pattern rather than many The 'record -> replay' mode used by the mocking framework.

In early versions of Python, you need to use unittest.mock separately. Get the mock from PyPI a> .

Get started quickly

When you access the object, Mock and MagicMock All properties and methods will be created and the details of their use saved. You can specify return values ​​or restrict accessible properties through configuration, and then assert how they are called:

>>>

>>> from unittest.mock import MagicMock
>>> thing = ProductionClass()
>>> thing.method = MagicMock(return_value=3)
>>> thing.method(3, 4, 5, key='value')
3
>>> thing.method.assert_called_with(3, 4, 5, key='value')

Set side effects through side_effect , which can be an exception thrown when the mock is called:

>>>

>>> from unittest.mock import Mock
>>> mock = Mock(side_effect=KeyError('foo'))
>>> mock()
Traceback (most recent call last):
 ...
KeyError: 'foo'

>>>

>>> values = {'a': 1, 'b': 2, 'c': 3}
>>> def side_effect(arg):
...     return values[arg]
...
>>> mock.side_effect = side_effect
>>> mock('a'), mock('b'), mock('c')
(1, 2, 3)
>>> mock.side_effect = [5, 4, 3, 2, 1]
>>> mock(), mock(), mock()
(5, 4, 3)

Mocks also have other ways to configure and control their behavior. For example, a mock can obtain its specification from an object by setting the spec parameter. If the attributes or methods accessed by the mock are not in the spec, an AttributeError error will be reported.

Use patch() to decorate/context manager, which makes it easier to test classes or objects under a module. The object you specify will be replaced with a mock (or other object) during the test and restored after the test is completed.

>>>

>>> from unittest.mock import patch
>>> @patch('module.ClassName2')
... @patch('module.ClassName1')
... def test(MockClass1, MockClass2):
...     module.ClassName1()
...     module.ClassName2()
...     assert MockClass1 is module.ClassName1
...     assert MockClass2 is module.ClassName2
...     assert MockClass1.called
...     assert MockClass2.called
...
>>> test()

Remark

When you nest patch decorators, mocks will be passed to decorator functions in execution order (Python decorator normal order). Since it is from the bottom up, in the above example, the incoming module.ClassName1 is mocked first.

Patch an object in the namespace of the search object using patch() . It's easy to use, read Where to patch to get started quickly.

patch() You can also use context management in the with statement.

>>>

>>> with patch.object(ProductionClass, 'method', return_value=None) as mock_method:
...     thing = ProductionClass()
...     thing.method(1, 2, 3)
...
>>> mock_method.assert_called_once_with(1, 2, 3)

There is also a patch.dict() which is used to set the values ​​in the dictionary within a certain range and change the dictionary at the end of the test Restore to its original state:

>>>

>>> foo = {'key': 'value'}
>>> original = foo.copy()
>>> with patch.dict(foo, {'newkey': 'newvalue'}, clear=True):
...     assert foo == {'newkey': 'newvalue'}
...
>>> assert foo == original

Mock supports Python Magic method . The easiest way to use pattern methods is to use MagicMock class. . It can do the following:

>>>

>>> mock = MagicMock()
>>> mock.__str__.return_value = 'foobarbaz'
>>> str(mock)
'foobarbaz'
>>> mock.__str__.assert_called_with()

Mock can designate functions (or other Mock instances) as magic methods, which will be called appropriately. MagicMock is a Mock with all magic methods (all useful methods) pre-created.

Here is an example using the magic methods of a normal Mock class

>>>

>>> mock = Mock()
>>> mock.__str__ = Mock(return_value='wheeeeee')
>>> str(mock)
'wheeeeee'

Using auto-speccing can ensure that the mock object in the test has the same API as the object to be replaced. In the patch, you can pass the autospec parameter to achieve automatic inference, or use create_autospec() Function. Automatic inference creates a mock object with the same properties and methods as the object being replaced, and any functions and methods (including constructors) have the same call signature as the real object.

This is done to ensure that improper use of mocks causes the same failures as production code:

>>>

>>> from unittest.mock import create_autospec
>>> def function(a, b, c):
...     pass
...
>>> mock_function = create_autospec(function, return_value='fishy')
>>> mock_function(1, 2, 3)
'fishy'
>>> mock_function.assert_called_once_with(1, 2, 3)
>>> mock_function('wrong arguments')
Traceback (most recent call last):
 ...
TypeError: <lambda>() takes exactly 3 arguments (1 given)

When using create_autospec() in a class, the signature of the __init__ method will be copied. In addition, it can When used on the calling object, the signature of the __call__ method will be copied.

Mock class

Mock is an object that can flexibly replace stubs and can test all code. Mock is callable, creating a new mock 1 when its properties are accessed. Accessing the same property will just return the same mock. Mock will save the call record, and you can know the call of the code through assertions.

MagicMock is a subclass of Mock which has all pre-created and usable magic methods . When you need to simulate non-callable objects, you can use NonCallableMock  and NonCallableMagicMock

patch() Decorators make it very convenient to use Mock objects to temporarily replace classes in a specific module . By default patch() will create a MagicMock for you. You can use patch() 's new_callable parameter specification instead  class. Mock

class unittest.mock.Mock(spec=Noneside_effect=Nonereturn_value=DEFAULTwraps=Nonename=Nonespec_set=Noneunsafe=False**kwargs)

Create a new Mock object. Specify the behavior of the Mock object via optional parameters:

  • spec: Either a list of strings to be given, or an existing object (class or instance) that serves as the mock object specification. If an object is passed in, a list of strings is generated by calling dir on the object (except for unsupported magic properties and methods). Accessing any attribute not in this list will trigger AttributeError .

    If spec is an object (not a list of strings), then __class__ test. isinstance() object. This allows the mock to pass the spec Returns the class of the 

  • spec_set : A stricter variant of spec . If this attribute is used, try to simulate set or get if the attribute is not present spec_set will throw AttributeError when it is contained in an object.

  • side_effect : A function that will be called whenever Mock is called. See the side_effect attribute. Useful for raising exceptions or dynamically changing return values. The function is called with the same parameters as the mock function, and the return value of the function is used as the return value unless DEFAULT is returned.

    In addition, side_effect can be an exception class or instance. At this point, an exception will be thrown when calling the simulation program.

    If side_effect is an iterable object, each call to mock will return the next value of the iterable object.

    Configuration side_effect 为 None Ready to clear sky.

  • return_value : The return value of calling mock. By default, a new Mock (created on first access). See the return_value attribute.

  • unsafe: By default, access any name to assert, < a i=4>assretasertaseert< Attributes starting with a i=9> or assrt will trigger AttributeError. Passing in  will allow access to these properties. unsafe=True

    New features in version 3.5.

  • wraps : The mock object to be wrapped. If wraps is not None , then calling Mock will pass the call to wraps< /span> object (therefore, attempting to access a non-existent property will raise < /span>  ). AttributeErrorwraps object (returns the actual result). Property access to a mock will return a Mock object that wraps the corresponding property of the 

    If return_value is explicitly specified, the wrapped object will not be returned when called, but return_value will be returned.  .

  • name : The name of the mock. Useful when debugging. The name is passed to the child mock.

You can also call mock with any keyword arguments. Once the mock is created, these properties are used to set the mock's properties. See the configure_mock() method for details.

assert_called()

Assert that the mock has been called at least once.

>>>

>>> mock = Mock()
>>> mock.method()
<Mock name='mock.method()' id='...'>
>>> mock.method.assert_called()

New features in version 3.6.

assert_called_once()

Asserts that the mock has been called exactly once.

>>>

>>> mock = Mock()
>>> mock.method()
<Mock name='mock.method()' id='...'>
>>> mock.method.assert_called_once()
>>> mock.method()
<Mock name='mock.method()' id='...'>
>>> mock.method.assert_called_once()
Traceback (most recent call last):
...
AssertionError: Expected 'method' to have been called once. Called 2 times.

New features in version 3.6.

assert_called_with(*args**kwargs)

This method is a convenience way of asserting that the last call has been made in a specific way:

>>>

>>> mock = Mock()
>>> mock.method(1, 2, 3, test='wow')
<Mock name='mock.method()' id='...'>
>>> mock.method.assert_called_with(1, 2, 3, test='wow')

assert_called_once_with(*args**kwargs)

Asserts that the mock has been called exactly once with the specified arguments passed to that call.

>>>

>>> mock = Mock(return_value=None)
>>> mock('foo', bar='baz')
>>> mock.assert_called_once_with('foo', bar='baz')
>>> mock('other', bar='values')
>>> mock.assert_called_once_with('other', bar='values')
Traceback (most recent call last):
  ...
AssertionError: Expected 'mock' to be called once. Called 2 times.

assert_any_call(*args**kwargs)

Asserts that the mock has been called with the specified arguments.

If mock  has been  called, the assertion passes, which is different from assert_called_with() then it must be the only call. assert_called_once_with() will only pass when the call is the latest one, and for assert_called_once_with() and 

>>>

>>> mock = Mock(return_value=None)
>>> mock(1, 2, arg='thing')
>>> mock('some', 'thing', 'else')
>>> mock.assert_any_call(1, 2, arg='thing')

assert_has_calls(callsany_order=False)

Asserts that the mock has been called with the specified parameters. The mock_calls list will be checked against these calls.

If any_order is false, the call must be made sequentially. There can be additional calls before or after the specified call.

If any_order is true then the calls can be in any order, but they must all be in  Appears in mock_calls .

>>>

>>> mock = Mock(return_value=None)
>>> mock(1)
>>> mock(2)
>>> mock(3)
>>> mock(4)
>>> calls = [call(2), call(3)]
>>> mock.assert_has_calls(calls)
>>> calls = [call(4), call(2), call(3)]
>>> mock.assert_has_calls(calls, any_order=True)

assert_not_called()

Assert that the mock has never been called.

>>>

>>> m = Mock()
>>> m.hello.assert_not_called()
>>> obj = m.hello()
>>> m.hello.assert_not_called()
Traceback (most recent call last):
  ...
AssertionError: Expected 'hello' to not have been called. Called 1 times.

New features in version 3.5.

reset_mock(*return_value=Falseside_effect=False)

The reset_mock method will reset all calling properties on the mock object:

>>>

>>> mock = Mock(return_value=None)
>>> mock('hello')
>>> mock.called
True
>>> mock.reset_mock()
>>> mock.called
False

Changed in version 3.6: Added two keyword-only arguments to the reset_mock function.

This is useful when you want to create a series of assertions that reuse the same object. Please note that reset_mock()  will not clear the return value, side_effect a> or any subproperty that you set by default using normal assignment. If you want to reset return_value or side_effect, set the corresponding The formal parameters are passed in True. Child mocks and return value mocks (if any) are also reset.

Remark

return_value, and side_effect are keyword arguments only.

mock_add_spec(specspec_set=False)

Add a description for the mock. spec can be an object or a list of strings. Only properties on spec can be obtained as properties from the mock.

If spec_set is true, only the attributes on spec can be set.

attach_mock(mockattribute)

Append a mock as an attribute to this one, replacing its name and parent. Calls to additional mocks will be logged in this one's method_calls and mock_calls in properties.

configure_mock(**kwargs)

Set properties on the mock via keyword arguments.

Properties plus return values ​​and side effects can be set on the child mock using standard dot notation and unwrapped a dictionary in the method call:

>>>

>>> mock = Mock()
>>> attrs = {'method.return_value': 3, 'other.side_effect': KeyError}
>>> mock.configure_mock(**attrs)
>>> mock.method()
3
>>> mock.other()
Traceback (most recent call last):
  ...
KeyError

The same operation can be achieved in the constructor call of mock:

>>>

>>> attrs = {'method.return_value': 3, 'other.side_effect': KeyError}
>>> mock = Mock(some_attribute='eggs', **attrs)
>>> mock.some_attribute
'eggs'
>>> mock.method()
3
>>> mock.other()
Traceback (most recent call last):
  ...
KeyError

The existence of configure_mock() makes it easier to configure the mock after it is created.

__your__()

The Mock object will limit the results of dir(some_mock) to useful results. For mocks with spec this also includes all allowed attributes of the mock.

Please see FILTER_DIR to learn what this filtering does and how to disable it.

_get_child_mock(**kw)

Create child mocks for properties and return values. By default the child mock will be of the same type as its parent. Subclasses of Mock may need to override this to customize how child mocks are created.

For non-callable mocks the callable variant will be used (rather than an arbitrary custom subclass).

called

A Boolean value indicating whether the mock object has been called:

>>>

>>> mock = Mock(return_value=None)
>>> mock.called
False
>>> mock()
>>> mock.called
True

call_count

An integer value that tells you how many times the mock object has been called:

>>>

>>> mock = Mock(return_value=None)
>>> mock.call_count
0
>>> mock()
>>> mock()
>>> mock.call_count
2

return_value

Set this to configure the value returned by calling this mock:

>>>

>>> mock = Mock()
>>> mock.return_value = 'fish'
>>> mock()
'fish'

The default return value is a mock object and you can configure it in the normal way:

>>>

>>> mock = Mock()
>>> mock.return_value.attribute = sentinel.Attribute
>>> mock.return_value()
<Mock name='mock()()' id='...'>
>>> mock.return_value.assert_called_with()

return_value can also be set in the constructor:

>>>

>>> mock = Mock(return_value=3)
>>> mock.return_value
3
>>> mock()
3

side_effect

This can either be a function to be called when the mock is called, a callable object, or an exception (class or instance) to be thrown.

If you pass in a function it will be called with the same parameters as the mock except that the function returns DEFAULT singleton Any other calls to the mock will subsequently return whatever the function returns. If the function returns DEFAULT then the mock will return its normal value (from return_value).

If you pass in an iterable object, it will be used to obtain an iterator that must produce a value on each call. This value can be an exception instance to be thrown, or a value to be returned to the mock from the call (DEFAULT is handled in the same way as a function ).

An example of a mock that throws exceptions (to test the API's exception handling):

>>>

>>> mock = Mock()
>>> mock.side_effect = Exception('Boom!')
>>> mock()
Traceback (most recent call last):
  ...
Exception: Boom!

Use side_effect to return a sequence containing multiple values:

>>>

>>> mock = Mock()
>>> mock.side_effect = [3, 2, 1]
>>> mock(), mock(), mock()
(3, 2, 1)

Use a callable object:

>>>

>>> mock = Mock(return_value=3)
>>> def side_effect(*args, **kwargs):
...     return DEFAULT
...
>>> mock.side_effect = side_effect
>>> mock()
3

side_effect can be set in the constructor. The following is an example of adding a value to this property and returning it when the mock is called:

>>>

>>> side_effect = lambda value: value + 1
>>> mock = Mock(side_effect=side_effect)
>>> mock(3)
4
>>> mock(-8)
-7

Set side_effect to None to clear it:

>>>

>>> m = Mock(side_effect=KeyError, return_value=3)
>>> m()
Traceback (most recent call last):
 ...
KeyError
>>> m.side_effect = None
>>> m()
3

call_args

This can be None (if the mock has not been called), or the arguments passed to the mock when it was last called. This will take the form of a tuple: the first member is also accessible via the args trait attribute, which is any positional argument (or an empty tuple) that the mock was called with, and The second member can also be accessed via the kwargs trait attribute, which is any keyword argument (or an empty dictionary).

>>>

>>> mock = Mock(return_value=None)
>>> print(mock.call_args)
None
>>> mock()
>>> mock.call_args
call()
>>> mock.call_args == ()
True
>>> mock(3, 4)
>>> mock.call_args
call(3, 4)
>>> mock.call_args == ((3, 4),)
True
>>> mock.call_args.args
(3, 4)
>>> mock.call_args.kwargs
{}
>>> mock(3, 4, 5, key='fish', next='w00t!')
>>> mock.call_args
call(3, 4, 5, key='fish', next='w00t!')
>>> mock.call_args.args
(3, 4, 5)
>>> mock.call_args.kwargs
{'key': 'fish', 'next': 'w00t!'}

call_args, and list call_args_listmethod_calls The members of a> and mock_calls are both call object. These are tuples of object properties so they can be unpacked to obtain individual parameters and create more complex assertions. See  call as a tuple.

Changed in version 3.8: Added args and kwargs feature attributes. properties.

call_args_list

This is a sorted list of all calls to the mock object (so the length of the list is the number of times it has been called). It will be an empty list before any calls are made. call objects can be used to conveniently construct call lists to be used with call_args_list Compared.

>>>

>>> mock = Mock(return_value=None)
>>> mock()
>>> mock(3, 4)
>>> mock(key='fish', next='w00t!')
>>> mock.call_args_list
[call(), call(3, 4), call(key='fish', next='w00t!')]
>>> expected = [(), ((3, 4),), ({'key': 'fish', 'next': 'w00t!'},)]
>>> mock.call_args_list == expected
True

The members of call_args_list are all call objects. They can be unpacked as tuples to obtain a single argument. See call as a tuple.

method_calls

In addition to tracking calls to itself, a mock also tracks access to methods and properties, as well as their  methods and properties:

>>>

>>> mock = Mock()
>>> mock.method()
<Mock name='mock.method()' id='...'>
>>> mock.property.method.attribute()
<Mock name='mock.property.method.attribute()' id='...'>
>>> mock.method_calls
[call.method(), call.property.method.attribute()]

The members of method_calls are all call objects. They can be unpacked as tuples to obtain a single argument. See call as a tuple.

mock_calls

mock_calls will record all calls to the mock object, its methods, and magic methods  a> return the mock of the value. and

>>>

>>> mock = MagicMock()
>>> result = mock(1, 2, 3)
>>> mock.first(a=3)
<MagicMock name='mock.first()' id='...'>
>>> mock.second()
<MagicMock name='mock.second()' id='...'>
>>> int(mock)
1
>>> result(1)
<MagicMock name='mock()()' id='...'>
>>> expected = [call(1, 2, 3), call.first(a=3), call.second(),
... call.__int__(), call()(1)]
>>> mock.mock_calls == expected
True

The members of mock_calls are all call objects. They can be unpacked as tuples to obtain a single argument. See call as a tuple.

Remark

The recording method of mock_calls means that when making nested calls, the formal parameters of the previous call will not be recorded and such comparisons will always be equal:

>>>

>>> mock = MagicMock()
>>> mock.top(a=3).bottom()
<MagicMock name='mock.top().bottom()' id='...'>
>>> mock.mock_calls
[call.top(a=3), call.top().bottom()]
>>> mock.mock_calls[-1] == call.top(a=-1).bottom()
True

__class__

Usually an object's __class__ attribute will return its type. For mock objects with spec , __class__ will return the spec class instead. This will allow mock objects to skip isinstance() tests for the objects they replace/mask:

>>>

>>> mock = Mock(spec=3)
>>> isinstance(mock, int)
True

__class__ can be assigned, which will allow mocks to skip isinstance() detection instead You are not required to use spec:

>>>

>>> mock = Mock()
>>> mock.__class__ = dict
>>> isinstance(mock, dict)
True

class unittest.mock.NonCallableMock(spec=Nonewraps=Nonename=Nonespec_set=None**kwargs)

Not callable Mock version. The formal parameters of its constructor have the same meaning as Mock , the difference is that return_value and side_effect have no meaning on non-callable mocks.

Using a class or instance as a mock object for spec or spec_set can skip isinstance() Test:

>>>

>>> mock = Mock(spec=SomeClass)
>>> isinstance(mock, SomeClass)
True
>>> mock = Mock(spec_set=SomeClass())
>>> isinstance(mock, SomeClass)
True

The Mock class has support for mock operation magic methods. See Magic Methods for complete details.

Both the mock operation class and the patch() decorator accept any keyword arguments for configuration. For the patch() decorator, keyword arguments will be passed to the constructor of the created mock. These keywords are used to configure mock properties:

>>>

>>> m = MagicMock(attribute=3, other='fish')
>>> m.attribute
3
>>> m.other
'fish'

The return value and side effects of the child mock can also be set in the same way using dotted tags. Since you can't use dotted names directly in the call you need to create a dictionary and unpack it using ** :

>>>

>>> attrs = {'method.return_value': 3, 'other.side_effect': KeyError}
>>> mock = Mock(some_attribute='eggs', **attrs)
>>> mock.some_attribute
'eggs'
>>> mock.method()
3
>>> mock.other()
Traceback (most recent call last):
  ...
KeyError

Created using spec (or spec_set) Calling a mock will introspect the signature of the specification object when matching the call to the mock. Therefore, it can match the parameters of the actual call without caring whether they are passed in positionally or by name:

>>>

>>> def f(a, b, c): pass
...
>>> mock = Mock(spec=f)
>>> mock(1, 2, c=3)
<Mock name='mock()' id='140161580456576'>
>>> mock.assert_called_with(1, 2, 3)
>>> mock.assert_called_with(a=1, b=2, c=3)

This applies to assert_called_with()assert_called_once_with()assert_has_calls() and assert_any_call(). When executing auto spec , it will also be applied to method calls on the mock object.

Changed in version 3.4: Added signature introspection on mock objects with specification and auto-specification

class unittest.mock.PropertyMock(*args**kwargs)

A mock intended to be used as a trait attribute or other descriptor of a class. PropertyMock provides __get__() and __set__() methods so that you can specify when it is extracted a return value.

When extracting a PropertyMock instance from an object, the mock will be called without any parameters. If set, the mock will be called with the set value.

>>>

>>> class Foo:
...     @property
...     def foo(self):
...         return 'something'
...     @foo.setter
...     def foo(self, value):
...         pass
...
>>> with patch('__main__.Foo.foo', new_callable=PropertyMock) as mock_foo:
...     mock_foo.return_value = 'mockity-mock'
...     this_foo = Foo()
...     print(this_foo.foo)
...     this_foo.foo = 6
...
mockity-mock
>>> mock_foo.mock_calls
[call(), call(6)]

Due to the way mock properties are stored you cannot directly attach PropertyMock to a mock object. But you can attach it to a mock type object:

>>>

>>> m = MagicMock()
>>> p = PropertyMock(return_value=3)
>>> type(m).foo = p
>>> m.foo
3
>>> p.assert_called_once_with()

class unittest.mock.AsyncMock(spec=Noneside_effect=Nonereturn_value=DEFAULTwraps=Nonename=Nonespec_set=Noneunsafe=False**kwargs)

Asynchronous version of MagicMock . AsyncMock The object will behave in such a way that the object will be recognized as an asynchronous function, and the result of its call will be an awaitable object.

>>>

>>> mock = AsyncMock()
>>> asyncio.iscoroutinefunction(mock)
True
>>> inspect.isawaitable(mock())  
True

The result of calling mock() is an asynchronous function, which after being waited for will have the result of side_effect or return_value :

  • If side_effect is a function, the asynchronous function will return the result of the function,

  • If side_effect is an exception, the asynchronous function will raise the exception,

  • If side_effect is an iterable object, the async function will return the next value of the iterable object, but if the result sequence is exhausted, it will raise immediately a> StopAsyncIteration,

  • If side_effect is not defined, the async function will return the value defined by return_value , therefore, by default, the asynchronous function will return a new AsyncMock object.

Will Mock or MagicMock  spec Setting it to an asynchronous function will cause a coroutine object to be returned after the call.

>>>

>>> async def async_func(): pass
...
>>> mock = MagicMock(async_func)
>>> mock
<MagicMock spec='function' id='...'>
>>> mock()  
<coroutine object AsyncMockMixin._mock_call at ...>

Will MockMagicMock or  AsyncMock 's spec is set to a class with asynchronous and synchronous functions, which will be automatically deleted. Synchronize functions and set them to MagicMock (if the superior mock is AsyncMock Or MagicMock) or Mock (if the superior mock is  Mock). All asynchronous functions will be AsyncMock.

>>>

>>> class ExampleClass:
...     def sync_foo():
...         pass
...     async def async_foo():
...         pass
...
>>> a_mock = AsyncMock(ExampleClass)
>>> a_mock.sync_foo
<MagicMock name='mock.sync_foo' id='...'>
>>> a_mock.async_foo
<AsyncMock name='mock.async_foo' id='...'>
>>> mock = Mock(ExampleClass)
>>> mock.sync_foo
<Mock name='mock.sync_foo' id='...'>
>>> mock.async_foo
<AsyncMock name='mock.async_foo' id='...'>

New features in version 3.8.

assert_awaited()

Asserts that the mock has been waited for at least once. Please note that this is separated from the called object and must use the await keyword:

>>>

>>> mock = AsyncMock()
>>> async def main(coroutine_mock):
...     await coroutine_mock
...
>>> coroutine_mock = mock()
>>> mock.called
True
>>> mock.assert_awaited()
Traceback (most recent call last):
...
AssertionError: Expected mock to have been awaited.
>>> asyncio.run(main(coroutine_mock))
>>> mock.assert_awaited()

assert_awaited_once()

Asserts that the mock has been waited for exactly once.

>>>

>>> mock = AsyncMock()
>>> async def main():
...     await mock()
...
>>> asyncio.run(main())
>>> mock.assert_awaited_once()
>>> asyncio.run(main())
>>> mock.method.assert_awaited_once()
Traceback (most recent call last):
...
AssertionError: Expected mock to have been awaited once. Awaited 2 times.

assert_awaited_with(*args**kwargs)

Assert that the specified parameters were passed in last time.

>>>

>>> mock = AsyncMock()
>>> async def main(*args, **kwargs):
...     await mock(*args, **kwargs)
...
>>> asyncio.run(main('foo', bar='bar'))
>>> mock.assert_awaited_with('foo', bar='bar')
>>> mock.assert_awaited_with('other')
Traceback (most recent call last):
...
AssertionError: expected call not found.
Expected: mock('other')
Actual: mock('foo', bar='bar')

assert_awaited_once_with(*args**kwargs)

Asserts that the mock has been waited for exactly once with the specified arguments.

>>>

>>> mock = AsyncMock()
>>> async def main(*args, **kwargs):
...     await mock(*args, **kwargs)
...
>>> asyncio.run(main('foo', bar='bar'))
>>> mock.assert_awaited_once_with('foo', bar='bar')
>>> asyncio.run(main('foo', bar='bar'))
>>> mock.assert_awaited_once_with('foo', bar='bar')
Traceback (most recent call last):
...
AssertionError: Expected mock to have been awaited once. Awaited 2 times.

assert_any_await(*args**kwargs)

Asserts that the mock has been awaited with the specified parameters.

>>>

>>> mock = AsyncMock()
>>> async def main(*args, **kwargs):
...     await mock(*args, **kwargs)
...
>>> asyncio.run(main('foo', bar='bar'))
>>> asyncio.run(main('hello'))
>>> mock.assert_any_await('foo', bar='bar')
>>> mock.assert_any_await('other')
Traceback (most recent call last):
...
AssertionError: mock('other') await not found

assert_has_awaits(callsany_order=False)

Asserts that the mock has been awaited with the specified call. The await_args_list list will be checked against these awaits.

If any_order is false, the waiting must be sequential. There can be additional calls before or after the specified wait.

If any_order is true then the waits can be in any order, but they must all be in  Appears in await_args_list .

>>>

>>> mock = AsyncMock()
>>> async def main(*args, **kwargs):
...     await mock(*args, **kwargs)
...
>>> calls = [call("foo"), call("bar")]
>>> mock.assert_has_awaits(calls)
Traceback (most recent call last):
...
AssertionError: Awaits not found.
Expected: [call('foo'), call('bar')]
Actual: []
>>> asyncio.run(main('foo'))
>>> asyncio.run(main('bar'))
>>> mock.assert_has_awaits(calls)

assert_not_awaited()

Asserts that mock was never awaited.

>>>

>>> mock = AsyncMock()
>>> mock.assert_not_awaited()

reset_mock(*args**kwargs)

See Mock.reset_mock(). It will also set await_count to 0 and await_args to None. And clear await_args_list.

await_count

An integer value that tracks how many times the mock object has been waited for.

>>>

>>> mock = AsyncMock()
>>> async def main():
...     await mock()
...
>>> asyncio.run(main())
>>> mock.await_count
1
>>> asyncio.run(main())
>>> mock.await_count
2

await_args

This may be None (if the mock has never been awaited), or the parameters attached to the last time this mock was awaited. Its function is the same as Mock.call_args .

>>>

>>> mock = AsyncMock()
>>> async def main(*args):
...     await mock(*args)
...
>>> mock.await_args
>>> asyncio.run(main('foo'))
>>> mock.await_args
call('foo')
>>> asyncio.run(main('bar'))
>>> mock.await_args
call('bar')

await_args_list

This is a list consisting of all waits performed on the mock object in sequence (so the length of the list is the number of times it was waited for). It will be an empty list before any waits are executed.

>>>

>>> mock = AsyncMock()
>>> async def main(*args):
...     await mock(*args)
...
>>> mock.await_args_list
[]
>>> asyncio.run(main('foo'))
>>> mock.await_args_list
[call('foo')]
>>> asyncio.run(main('bar'))
>>> mock.await_args_list
[call('foo'), call('bar')]

transfer

Mock objects are callable objects. The call will return the collection of values ​​as the return_value attribute. The default return value is a new Mock object; it is created the first time the return value is accessed (either explicitly or by calling Mock) - but it is saved and returns the same object each time.

Calls to this object will be recorded in call_args and call_args_list and other attributes.

If side_effect is set then it will be called after the call has been logged, so if side_effect raises The call will still be logged if an exception occurs.

The simplest way to make a mock throw an exception when called is to set side_effect to an exception class or instance:

>>>

>>> m = MagicMock(side_effect=IndexError)
>>> m(1, 2, 3)
Traceback (most recent call last):
  ...
IndexError
>>> m.mock_calls
[call(1, 2, 3)]
>>> m.side_effect = KeyError('Bang!')
>>> m('two', 'three', 'four')
Traceback (most recent call last):
  ...
KeyError: 'Bang!'
>>> m.mock_calls
[call(1, 2, 3), call('two', 'three', 'four')]

If side_effect is a function, the object returned by the function is the object returned by calling the mock. side_effect The function will be called with the same parameters as the mock. This allows you to dynamically change the return value based on input:

>>>

>>> def side_effect(value):
...     return value + 1
...
>>> m = MagicMock(side_effect=side_effect)
>>> m(1)
2
>>> m(2)
3
>>> m.mock_calls
[call(1), call(2)]

If you want the mock to still return the default return value (a new mock object), or any set return value, there are two ways to do this. Return  from within side_effect , or return DEFAULT:mock.return_value

>>>

>>> m = MagicMock()
>>> def side_effect(*args, **kwargs):
...     return m.return_value
...
>>> m.side_effect = side_effect
>>> m.return_value = 3
>>> m()
3
>>> def side_effect(*args, **kwargs):
...     return DEFAULT
...
>>> m.side_effect = side_effect
>>> m()
3

To remove a side_effect and return to the default behavior, set side_effect to None:< /span>

>>>

>>> m = MagicMock(return_value=6)
>>> def side_effect(*args, **kwargs):
...     return 3
...
>>> m.side_effect = side_effect
>>> m()
3
>>> m.side_effect = None
>>> m()
6

side_effect can also be any iterable object. Repeated calls to this mock will return values ​​from this iterable (until the iterable is exhausted and causes StopIteration to be raised):< /span>

>>>

>>> m = MagicMock(side_effect=[1, 2, 3])
>>> m()
1
>>> m()
2
>>> m()
3
>>> m()
Traceback (most recent call last):
  ...
StopIteration

If any members of the iterable are exceptions they will be raised rather than returned:

>>>

>>> iterable = (33, ValueError, 66)
>>> m = MagicMock(side_effect=iterable)
>>> m()
33
>>> m()
Traceback (most recent call last):
 ...
ValueError
>>> m()
66

Delete attributes

The Mock object creates properties as needed. This allows them to pretend to be any type of object.

You may want a mock object returned when calling hasattr() False, or when getting AttributeError is raised when an attribute is specified. You can do this by providing an object as the mock's spec property, but this is not always convenient.

You can "block" attributes by removing them. Once the attribute is deleted, accessing it will raise AttributeError.

>>>

>>> mock = MagicMock()
>>> hasattr(mock, 'm')
True
>>> del mock.m
>>> hasattr(mock, 'm')
False
>>> del mock.f
>>> mock.f
Traceback (most recent call last):
    ...
AttributeError: f

Mock's name and name attribute

Since "name" is one of the parameters of the Mock constructor, if you want your mock object to have "name" Property You cannot pass in this parameter when creating. There are two alternatives. One option is to use configure_mock():

>>>

>>> mock = MagicMock()
>>> mock.configure_mock(name='my_name')
>>> mock.name
'my_name'

A simpler option is to simply set the "name" attribute after the mock is created:

>>>

>>> mock = MagicMock()
>>> mock.name = "foo"

Attach Mock as property

When you attach a mock as a property of another mock (or as a return value) it becomes a "child object" of that mock. Calls to the child object will be recorded in the parent object's method_calls and mock_calls In properties. This works either for configuring child mocks and then attaching them to the parent object, or for attaching the mocks to the parent object which will log all calls to the child objects and allow you to create assertions about the order of calls between mocks:

>>>

>>> parent = MagicMock()
>>> child1 = MagicMock(return_value=None)
>>> child2 = MagicMock(return_value=None)
>>> parent.child1 = child1
>>> parent.child2 = child2
>>> child1(1)
>>> child2(2)
>>> parent.mock_calls
[call.child1(1), call.child2(2)]

An exception to this is if the mock has a name set. This allows you to avoid the effects of the "parent" if for some reason you don't want it to happen.

>>>

>>> mock = MagicMock()
>>> not_a_child = MagicMock(name='not-a-child')
>>> mock.attribute = not_a_child
>>> mock.attribute()
<MagicMock name='not-a-child()' id='...'>
>>> mock.mock_calls
[]

Mocks created by patch() will be automatically assigned names. To attach a named mock to a parent object you should use the attach_mock() method:

>>>

>>> thing1 = object()
>>> thing2 = object()
>>> parent = MagicMock()
>>> with patch('__main__.thing1', return_value=None) as child1:
...     with patch('__main__.thing2', return_value=None) as child2:
...         parent.attach_mock(child1, 'child1')
...         parent.attach_mock(child2, 'child2')
...         child1('one')
...         child2('two')
...
>>> parent.mock_calls
[call.child1('one'), call.child2('two')]

1

The only exceptions are magic methods and properties (whose names are preceded and followed by double underscores). Mock will not create them but will raise AttributeError. This is because the interpreter will often request these methods implicitly, and will get a new Mock object when it is ready to accept a magic method. >Confused. If you need magic method support please see Magic Methods.

patch decorator

The patch decorator is only used to add patches to objects within the scope of the function they decorate. They will automatically perform patch removal for you, even if an exception is thrown. All these functions can also be used in with statements or as class decorators.

patch

Remark

The key to the problem is to patch in the correct namespace. See the section where to patch .

unittest.mock.patch(targetnew=DEFAULTspec=Nonecreate=Falsespec_set=Noneautospec=Nonenew_callable=None**kwargs)

patch() can be used as a function decorator, class decorator or context manager. Inside the function or with statement, target will be marked with a new object patch. The patch will be undone when the function/with statement exits.

If new is omitted, then if the patched object is an asynchronous function then target will be replaced by < a i=3>AsyncMock Otherwise, replace it with MagicMock. If patch() is used as a decorator and new is omitted, Then the created mock will be passed into the decorated function as an additional parameter. If patch() is used as a context manager then the created mock will be returned by that context manager.

target should be a string of the form 'package.module.ClassName' . target will be imported and the specified object will be replaced with the new object , so target must be an environment that can call patch() from you imported in . target will be imported when the decorated function is executed, not when decorated.

spec and spec_set keyword arguments will be passed to MagicMock, if patch created this object for you.

Alternatively you can pass in spec=True or spec_set=True, which will cause patch to pass in the simulated object as a spec/spec_set object.

new_callable allows you to specify a different class, or callable object, that will be called to create new< a i=3> object. By default AsyncMock will be specified for asynchronous functions, MagicMock will be used to other functions.

Another stronger form of spec is autospec. If you set autospec=True then the mock will be created with the spec from the replaced object. All properties of the mock will also have the spec of the corresponding properties of the replaced object. Mocked methods and functions will check their arguments and raise a TypeError  if they are called with the wrong signature. For mocks that replace a class, their return values ​​(i.e. 'instances') will have the same spec as the class. See the create_autospec() function and the autospec.

In addition to autospec=True you can also pass autospec=some_object to use an arbitrary object as spec instead of the replaced object.

By default patch() will not be able to replace non-existing properties. If you pass in create=True and the attribute does not exist, patch will create the attribute for you when the patched function is called, and delete it again when the patched function exits . This is suitable for writing tests against properties created by production code at runtime. It is turned off by default because it is dangerous. When it's turned on you'll be able to write passing tests for APIs that don't actually exist!

Remark

Changed in version 3.5: If you want to patch a built-in function of a module, you do not need to pass in create=True, it will be added by default.

Patch can be used as a TestCase class decorator. Its role is to decorate each test method in the class. This will reduce boilerplate code when your test methods share the same patch set. patch() will find tests by looking for names starting with patch.TEST_PREFIX . Its default value is 'test', which is consistent with the way unittest hits the test. You can specify other prefixes by setting patch.TEST_PREFIX .

Patch can be used as a context manager via the with statement. The patch will then be applied to the indented code block of the with statement. If you use "as" then the patched object will be bound to the name after "as"; this is useful when patch() Create a mock object for you.

patch() accepts any keyword arguments. If the patched object is asynchronous, these parameters will be passed to AsyncMock, otherwise passed to MagicMock a>, or the specified new_callable.

patch.dict(...)patch.multiple(...) and patch.object(...) can be used in other usage scenarios.

patch() serves as a function decorator, creating a mock for you and passing it into the decorated function:

>>>

>>> @patch('__main__.SomeClass')
... def function(normal_argument, mock_class):
...     print(mock_class is SomeClass)
...
>>> function(None)
True

Patching a class will replace the class with an  instance of MagicMock < a i=4>. If this class is instantiated in the code under test then it will be the return_value of the mock to be used.

If the class is instantiated multiple times you can use side_effect to return a new mock each time. Or you can set return_value to any object you wish.

To configure a return value on a method of an  instance of the patched class you must configure a return value on return_value operate. For example:

>>>

>>> class Class:
...     def method(self):
...         pass
...
>>> with patch('__main__.Class') as MockClass:
...     instance = MockClass.return_value
...     instance.method.return_value = 'foo'
...     assert Class() is instance
...     assert Class().method() == 'foo'
...

If you use spec or spec_set and spec_set a> , then the return value of the created mock will have the same spec. class replaces patch()

>>>

>>> Original = Class
>>> patcher = patch('__main__.Class', spec=True)
>>> MockClass = patcher.start()
>>> instance = MockClass()
>>> assert isinstance(instance, Original)
>>> patcher.stop()

new_callable The parameter is suitable for when you want to use other classes to replace the created mock. The default MagicMock occasions. For example, if you want to use NonCallableMock:

>>>

>>> thing = object()
>>> with patch('__main__.thing', new_callable=NonCallableMock) as mock_thing:
...     assert thing is mock_thing
...     thing()
...
Traceback (most recent call last):
  ...
TypeError: 'NonCallableMock' object is not callable

Another usage scenario is to replace an object with an instance of io.StringIO :

>>>

>>> from io import StringIO
>>> def foo():
...     print('Something')
...
>>> @patch('sys.stdout', new_callable=StringIO)
... def test(mock_stdout):
...     foo()
...     assert mock_stdout.getvalue() == 'Something\n'
...
>>> test()

When patch() creates a mock for you, usually the first thing you need to do is configure the mock. Some configuration can be done in calls to patch. Any keyword arguments you pass in when calling will be used to set properties on the mock created:

>>>

>>> patcher = patch('__main__.thing', first='one', second='two')
>>> mock_thing = patcher.start()
>>> mock_thing.first
'one'
>>> mock_thing.second
'two'

In addition to the properties of the created mock, such as return_value and side_effect Calling** patch()  using , you can also configure the properties of the sub-mock. Passing these properties directly as keyword arguments is semantically invalid, but it is still possible to expand a dictionary keyed by these properties into a 

>>>

>>> config = {'method.return_value': 3, 'other.side_effect': KeyError}
>>> patcher = patch('__main__.thing', **config)
>>> mock_thing = patcher.start()
>>> mock_thing.method()
3
>>> mock_thing.other()
Traceback (most recent call last):
  ...
KeyError

By default, attempts to patch a function (or method or attribute in a class) that does not exist in a module will fail and raise AttributeError< /span>:

>>>

>>> @patch('sys.non_existing_attribute', 42)
... def test():
...     assert sys.non_existing_attribute == 42
...
>>> test()
Traceback (most recent call last):
  ...
AttributeError: <module 'sys' (built-in)> does not have the attribute 'non_existing_attribute'

But adding  to the call to patch() will make the previous example work as expected : create=True

>>>

>>> @patch('sys.non_existing_attribute', 42, create=True)
... def test(mock_stdout):
...     assert sys.non_existing_attribute == 42
...
>>> test()

Changed in version 3.8: patch() will now return a  if the target is an asynchronous function AsyncMock.

patch.object

patch.object(targetattributenew=DEFAULTspec=Nonecreate=Falsespec_set=Noneautospec=Nonenew_callable=None**kwargs)

Use a mock object as the member of the specified name (attributetarget) a>) patch.

patch.object() can be used as a decorator, class decorator or context manager. newspeccreate spec_setautospec and new_callable and other parameters have the same meaning as patch() . Similar to patch() , patch.object() accepts any key Word parameters are used to configure the mock object it creates.

When used as a class decorator patch.object() will recognize patch.TEST_PREFIX as the selected wrapper Method standards.

You can call patch.object() with three parameters or two parameters. The three-argument form will accept the object to be patched, the name of the property, and the object that will replace the property.

When calling the form with two arguments you will omit the replacement object, and a mock will be created for you and passed as an additional argument to the decorated function:

>>>

>>> @patch.object(SomeClass, 'class_method')
... def test(mock_method):
...     SomeClass.class_method(3)
...     mock_method.assert_called_with(3)
...
>>> test()

passed to patch.object() speccreate and other parameters have the same meaning as the parameters of the same name of patch() same.

patch.dict

patch.dict(in_dictvalues=()clear=False**kwargs)

Patches a dictionary or dictionary-like object and, after testing, restores the directory to its original state.

in_dict can be a dictionary or mapping container. If it's a map then it must support at least getting, setting, and deleting entries as well as iterating over keys.

in_dict can also be a string specifying the name of the dictionary, which will then be obtained through the import operation.

values can be a dictionary of values ​​to be set in the dictionary. values can also be an iterable object containing (key, value) pairs.

If clear is true, the dictionary will be cleared before setting new values.

patch.dict() can also be called with any keyword arguments to set the values ​​in the dictionary.

Changed in version 3.8: patch.dict() will now return the patched dictionary when used as a context manager. now returns the patched dictionary when used as a context manager.

patch.dict() can be used as a context manager, decorator or class decorator:

>>>

>>> foo = {}
>>> @patch.dict(foo, {'newkey': 'newvalue'})
... def test():
...     assert foo == {'newkey': 'newvalue'}
...
>>> test()
>>> assert foo == {}

When used as a class decorator patch.dict() will recognize patch.TEST_PREFIX (default is 'test') as a criterion for selecting the packaging method:

>>>

>>> import os
>>> import unittest
>>> from unittest.mock import patch
>>> @patch.dict('os.environ', {'newkey': 'newvalue'})
... class TestSample(unittest.TestCase):
...     def test_sample(self):
...         self.assertEqual(os.environ['newkey'], 'newvalue')

If you are using a different prefix for your tests, you can notify the patcher of the different prefix by setting patch.TEST_PREFIX . See TEST_PREFIX for details on how to modify this value.

patch.dict() can be used to add members to a dictionary, or simply let the test modify a dictionary and ensure that the dictionary is restored when the test ends.

>>>

>>> foo = {}
>>> with patch.dict(foo, {'newkey': 'newvalue'}) as patched_foo:
...     assert foo == {'newkey': 'newvalue'}
...     assert patched_foo == {'newkey': 'newvalue'}
...     # You can add, update or delete keys of foo (or patched_foo, it's the same dict)
...     patched_foo['spam'] = 'eggs'
...
>>> assert foo == {}
>>> assert patched_foo == {}

>>>

>>> import os
>>> with patch.dict('os.environ', {'newkey': 'newvalue'}):
...     print(os.environ['newkey'])
...
newvalue
>>> assert 'newkey' not in os.environ

You can use keywords in the patch.dict() call to set the value of the dictionary:

>>>

>>> mymodule = MagicMock()
>>> mymodule.function.return_value = 'fish'
>>> with patch.dict('sys.modules', mymodule=mymodule):
...     import mymodule
...     mymodule.function('some', 'args')
...
'fish'

patch.dict() can be used with dictionary-like objects that are not actually dictionaries. At a minimum, they must support entry getting, setting, deleting, and either iteration or member detection. This corresponds to the magic methods __getitem__()__setitem__()__delitem__() and . __iter__() or __contains__()

>>>

>>> class Container:
...     def __init__(self):
...         self.values = {}
... def __gettime__(self, name):
...         return self.values[name]
...     def __setitem__(self, name, value):
...         self.values[name] = value
...     def __delitem__(self, name):
...         del self.values[name]
...     def __iter__(self):
...         return iter(self.values)
...
>>> thing = Container()
>>> thing['one'] = 1
>>> with patch.dict(thing, one=2, two=3):
...     assert thing['one'] == 2
...     assert thing['two'] == 3
...
>>> assert thing['one'] == 1
>>> assert list(thing) == ['one']

patch.multiple

patch.multiple(targetspec=Nonecreate=Falsespec_set=Noneautospec=Nonenew_callable=None**kwargs)

Perform multiple patches in a single call. It accepts the object to be patched (an object or a string obtained by importing the object) and keyword arguments for the patch:

with patch.multiple(settings, FIRST_PATCH='one', SECOND_PATCH='two'):
    ...

If you want patch.multiple() to create a mock for you, use DEFAULT is used as context management A dictionary will be returned. patch.multiple() as the value. The mock created in this case will be passed into the decorated function through keyword arguments, and when 

patch.multiple() can be used as a decorator, class decorator or context manager. specspec_setcreate autospec and new_callable etc. The meaning of the parameters is the same as patch() . These parameters will be applied to patch.multiple() for all Patch.

When used as a class decorator patch.multiple() will recognize patch.TEST_PREFIX as the choice Standards for packaging methods.

If you want patch.multiple() to create mocks for you, then you can use DEFAULT  as the value. If you use patch.multiple() as a decorator, the created mock will be passed into the decorated function as a keyword argument.

>>>

>>> thing = object()
>>> other = object()

>>> @patch.multiple('__main__', thing=DEFAULT, other=DEFAULT)
... def test_function(thing, other):
...     assert isinstance(thing, MagicMock)
...     assert isinstance(other, MagicMock)
...
>>> test_function()

patch.multiple() can be nested with other patch decorators, but the parameters passed as keywords must be placed in patch() After the standard parameters created :

>>>

>>> @patch('sys.exit')
... @patch.multiple('__main__', thing=DEFAULT, other=DEFAULT)
... def test_function(mock_exit, other, thing):
...     assert 'other' in repr(other)
...     assert 'thing' in repr(thing)
...     assert 'exit' in repr(mock_exit)
...
>>> test_function()

If patch.multiple() is used as a context manager, the return value of the context manager will be a value created with Dictionary of mock names with keys:

>>>

>>> with patch.multiple('__main__', thing=DEFAULT, other=DEFAULT) as values:
...     assert 'other' in repr(values['other'])
...     assert 'thing' in repr(values['thing'])
...     assert values['thing'] is thing
...     assert values['other'] is other
...

Patch methods: start and stop

All patch objects have start() and stop() methods. Using these methods makes it easier to patch setUp methods, and allows you to apply multiple patches without nesting decorators or with statements.

To use these methods please call patch()patch.object() in the normal way  or patch.dict() and retain a pointer to the returned patcher object Quote. You can then call start() to patch it in place and stop() to restore it.

If you use patch() to create your own mock, you will be able to return it by calling patcher.start it.

>>>

>>> patcher = patch('package.module.ClassName')
>>> from package import module
>>> original = module.ClassName
>>> new_mock = patcher.start()
>>> assert module.ClassName is not original
>>> assert module.ClassName is new_mock
>>> patcher.stop()
>>> assert module.ClassName is original
>>> assert module.ClassName is not new_mock

A typical application scenario for this operation is to perform multiple patches in the  method of a TestCase : setUp

>>>

>>> class MyTest(unittest.TestCase):
...     def setUp(self):
...         self.patcher1 = patch('package.module.Class1')
...         self.patcher2 = patch('package.module.Class2')
...         self.MockClass1 = self.patcher1.start()
...         self.MockClass2 = self.patcher2.start()
...
...     def tearDown(self):
...         self.patcher1.stop()
...         self.patcher2.stop()
...
...     def test_something(self):
...         assert package.module.Class1 is self.MockClass1
...         assert package.module.Class2 is self.MockClass2
...
>>> MyTest('test_something').run()

careful

If you want to use this trick you must ensure that the patch is "restored" by calling stop . This may be more troublesome than you think, because if an exception is thrown in setUp then tearDown will not be called. unittest.TestCase.addCleanup() can simplify this operation:

>>>

>>> class MyTest(unittest.TestCase):
...     def setUp(self):
...         patcher = patch('package.module.Class')
...         self.MockClass = patcher.start()
...         self.addCleanup(patcher.stop)
...
...     def test_something(self):
...         assert package.module.Class is self.MockClass
...

An additional benefit is that you no longer need to keep a reference to the patcher object.

You can also stop all started patches by using patch.stopall() .

patch.stopall()

Stop all active patches. Only patches initiated via start will be stopped.

Patching built-in functions

You can patch any built-in function in a module. The following example is to patch the built-in function ord() :

>>>

>>> @patch('__main__.ord')
... def test(mock_ord):
...     mock_ord.return_value = 101
...     print(ord('c'))
...
>>> test()
101

TEST_PREFIX

All patches can be used as class decorators. When used in this way they will wrap every test method in the class. The patch will recognize methods whose names begin with 'test' as test methods. This is the same as the default way unittest.TestLoader finds test methods.

You may want to use a different prefix for your tests. You can tell the patcher a different prefix by setting patch.TEST_PREFIX :

>>>

>>> patch.TEST_PREFIX = 'foo'
>>> value = 3
>>>
>>> @patch('__main__.value', 'not three')
... class Thing:
...     def foo_one(self):
...         print(value)
...     def foo_two(self):
...         print(value)
...
>>>
>>> Thing().foo_one()
not three
>>> Thing().foo_two()
not three
>>> value
3

Nested patch decorator

If you want to apply multiple patches then you can simply stack multiple decorators.

You can stack multiple patch decorators using the following pattern:

>>>

>>> @patch.object(SomeClass, 'class_method')
... @patch.object(SomeClass, 'static_method')
... def test(mock1, mock2):
...     assert SomeClass.static_method is mock1
...     assert SomeClass.class_method is mock2
...     SomeClass.static_method('foo')
...     SomeClass.class_method('bar')
...     return mock1, mock2
...
>>> mock1, mock2 = test()
>>> mock1.assert_called_once_with('foo')
>>> mock2.assert_called_once_with('bar')

Please note that decorators are applied from bottom to top. This is the standard way of applying decorators in Python. The order in which the mocks are created and passed into your test function will also match this order.

location of patch

patch() points to another object by (temporarily) modifying its name objects to function. There can be multiple names pointing to any single object, so for the patch to work you must make sure you have patched the name used by the system being tested.

The basic principle is that you patch the object  where it is found , which is not necessarily where it is defined. A set of examples will help clarify this.

Imagine we have a project with the following structure that we want to test:

a.py
    -> Defines SomeClass

b.py
    -> from a import SomeClass
    -> some_function instantiates SomeClass

Now we want to test some_function but we want to use patch() to simulate < a i=4>. The problem is that when we import module b, we will have to have it import from module a . If we use patch() to simulate  then it will not have an impact on our tests; module b has Having a reference to  the real  so it doesn't look like our patch has any impact. SomeClassSomeClassa.SomeClass SomeClass

The key is to patch SomeClass where it is used (or where it is found). In this case actually some_function will look for SomeClass in module b, where we have already imported it. The patch should look like this:

@patch('b.SomeClass')

However, consider another scenario where instead of from a import SomeClass module b executes import a and some_function uses a.SomeClass. Both import forms are common. In this case the class we want to patch will be found in that module and we must patch a.SomeClass instead:

@patch('a.SomeClass')

Patches descriptors and proxy objects

Both patch and patch.object can correctly patch and restore the descriptor: Contains Class methods, static methods, and trait properties. You should patch them on the class rather than the instance. They also apply to parts of proxy attribute access, such as django settings object.

MagicMock and magic method support

Simulate magic methods

Mock supports simulating Python protocol methods, or "magic methods". This allows mock objects to replace containers or other objects that implement Python protocols.

Because magic methods are looked up differently than normal methods 2, this support uses a special implementation. This means that only specific magic methods are supported. Supported are almost all magic methods. If there is something you need that is missing please let us know.

You can mock magic methods by setting them in a function or mock instance. If you are using a function it must accept self as the first argument  3.

>>>

>>> def __str__(self):
...     return 'fooble'
...
>>> mock = Mock()
>>> mock.__str__ = __str__
>>> str(mock)
'fooble'

>>>

>>> mock = Mock()
>>> mock.__str__ = Mock()
>>> mock.__str__.return_value = 'fooble'
>>> str(mock)
'fooble'

>>>

>>> mock = Mock()
>>> mock.__iter__ = Mock(return_value=iter([]))
>>> list(mock)
[]

One such application scenario is to simulate an object as a context manager in the with statement:

>>>

>>> mock = Mock()
>>> mock.__enter__ = Mock(return_value='foo')
>>> mock.__exit__ = Mock(return_value=False)
>>> with mock as m:
...     assert m == 'foo'
...
>>> mock.__enter__.assert_called_with()
>>> mock.__exit__.assert_called_with(None, None, None)

Calls to magic methods will not appear in method_calls , but they will be recorded in  in mock_calls .

Remark

If you use spec keyword arguments to create a mock then trying to set a magic method that is not included in the spec will raise  AttributeError.

The complete list of supported magic methods is as follows:

  • __hash____sizeof____repr__ 和 __str__

  • __dir____format__ 和 __subclasses__

  • __round____floor____trunc__ 和 __ceil__

  • Ratio calculation: __lt____gt____le____ge____eq__ 和 __ne__

  • Container method: __getitem____setitem____delitem____contains__ 和 __len____iter____reversed____missing__

  • Sentence manager: __enter____exit____aenter__ Japanese __aexit__

  • Monocular numerical calculation methods: __neg____pos__ and __invert__

  • Number computation method (comprehensive right side Japanese original two types format): __add____sub____mul____matmul____truediv____floordiv____mod____divmod____lshift____rshift____and____xor____or__ sum __pow__

  • Number conversion method: __complex____int____float__ sum __index__

  • Descriptor method: __get____set__ and __delete__

  • Containment method: __reduce____reduce_ex____getinitargs____getnewargs____getstate__ 和 __setstate__

  • File system path representation: __fspath__

  • 异步迭代方法: __aiter__ and __anext__

在 3.8 版更改: 增加了对 os.PathLike.__fspath__() 的支持。

在 3.8 版更改: 增加了对 __aenter____aexit____aiter__ 和 __anext__ 的支持。

下列方法均存在但是 不受 支持,因为它们或者被 mock 所使用,或者无法动态设置,或者可能导致问题:

  • __getattr____setattr____init__ 和 __new__

  • __prepare____instancecheck____subclasscheck____del__

MagicMock

存在两个版本的 MagicMockMagicMock 和 NonCallableMagicMock.

class unittest.mock.MagicMock(*args**kw)

MagicMock 是包含了大部分魔术方法的默认实现的 Mock 的子类。 你可以使用 MagicMock 而无须自行配置魔术方法。without having to configure the magic methods yourself.

构造器形参的含义与 Mock 的相同。

如果你使用了 spec 或 spec_set 参数则将 只有 存在于 spec 中的魔术方法会被创建。

class unittest.mock.NonCallableMagicMock(*args**kw)

MagicMock 的不可调用版本。

其构造器的形参具有与 MagicMock 相同的含义,区别在于 return_value 和 side_effect 在不可调用的 mock 上没有意义。

魔术方法是通过 MagicMock 对象来设置的,因此你可以用通常的方式来配置它们并使用它们:

>>>

>>> mock = MagicMock()
>>> mock[3] = 'fish'
>>> mock.__setitem__.assert_called_with(3, 'fish')
>>> mock.__getitem__.return_value = 'result'
>>> mock[2]
'result'

在默认情况下许多协议方法都需要返回特定类型的对象。 这些方法都预先配置了默认的返回值,以便它们在你对返回值不感兴趣时可以不做任何事就能被使用。 如果你想要修改默认值则你仍然可以手动 设置 返回值。

方法及其默认返回值:

  • __lt__NotImplemented

  • __gt__NotImplemented

  • __le__NotImplemented

  • __ge__NotImplemented

  • __int__1

  • __contains__False

  • __len__0

  • __iter__iter([])

  • __exit__False

  • __aexit__False

  • __complex__1j

  • __float__1.0

  • __bool__True

  • __index__1

  • __hash__: mock 的默认 hash

  • __str__: mock 的默认 str

  • __sizeof__: mock 的默认 sizeof

例如:

>>>

>>> mock = MagicMock()
>>> int(mock)
1
>>> len(mock)
0
>>> list(mock)
[]
>>> object() in mock
False

两个相等性方法 __eq__() 和 __ne__() 是特殊的。 它们基于标识号进行默认的相等性比较,使用 side_effect 属性,除非你修改它们的返回值以返回其他内容:

>>>

>>> MagicMock() == 3
False
>>> MagicMock() != 3
True
>>> mock = MagicMock()
>>> mock.__eq__.return_value = True
>>> mock == 3
True

MagicMock.__iter__() 的返回值可以是任意可迭代对象而不要求必须是迭代器:

>>>

>>> mock = MagicMock()
>>> mock.__iter__.return_value = ['a', 'b', 'c']
>>> list(mock)
['a', 'b', 'c']
>>> list(mock)
['a', 'b', 'c']

如果返回值  迭代器,则对其执行一次迭代就会将它耗尽因而后续执行的迭代将会输出空列表:

>>>

>>> mock.__iter__.return_value = iter(['a', 'b', 'c'])
>>> list(mock)
['a', 'b', 'c']
>>> list(mock)
[]

MagicMock 已配置了所有受支持的魔术方法,只有某些晦涩和过时的魔术方法是例外。 如果你需要仍然可以设置它们。

在 MagicMock 中受到支持但默认未被设置的魔术方法有:

  • __subclasses__

  • __dir__

  • __format__

  • __get____set__ 和 __delete__

  • __reversed__ 和 __missing__

  • __reduce____reduce_ex____getinitargs____getnewargs____getstate__ 和 __setstate__

  • __getformat__

2

魔术方法 应当 是在类中而不是在实例中查找。 不同的 Python 版本对这个规则的应用并不一致。 受支持的协议方法应当适用于所有受支持的 Python 版本。

3

该函数基本上是与类挂钩的,但每个 Mock 实例都会与其他实例保持隔离。

辅助对象

sentinel

unittest.mock.sentinel

sentinel 对象提供了一种为你的测试提供独特对象的便捷方式。

属性是在你通过名称访问它们时按需创建的。 访问相同的属性将始终返回相同的对象。 返回的对象会有一个合理的 repr 以使测试失败消息易于理解。

Changed in version 3.7: sentinel attributes are now copied when they are copy or < Save its identity when a i=4>pickle .

When testing you may need to test whether a specific object is passed as a parameter to another method, or returned by it. Common practice is to create a sentinel object with a specified name to perform this kind of testing. sentinel provides a convenient way to create and test identities for such objects.

In this example we apply a convenience patch to method to return sentinel.some_object:

>>>

>>> real = ProductionClass()
>>> real.method = Mock(name="method")
>>> real.method.return_value = sentinel.some_object
>>> result = real.method()
>>> assert result is sentinel.some_object
>>> result
sentinel.some_object

DEFAULT

unittest.mock.DEFAULT

The DEFAULT object is a pre-created sentinel (actually sentinel.DEFAULT). It can be used by the side_effect function to indicate that it should use the normal return value.

call

unittest.mock.call(*args**kwargs)

call() is a helper object that creates simpler assertions for use with call_argscall_args_listmock_calls and  method_calls for comparison. call() can also be used with assert_has_calls() .

>>>

>>> m = MagicMock(return_value=None)
>>> m(1, 2, a='foo', b='bar')
>>> m()
>>> m.call_args_list == [call(1, 2, a='foo', b='bar'), call()]
True

call.call_list()

For call objects that represent multiple calls,call_list() will return a list containing all intermediate calls as well as the final call.

call_list is particularly useful for creating assertions for "chained calls". Chained calls are multiple calls executed in one line of code. This will result in multiple entries in a mock mock_calls. Manually constructing the sequence of calls would be tedious.

call_list() can construct a sequence containing multiple calls based on the same chain call:

>>>

>>> m = MagicMock()
>>> m(1).method(arg='foo').other('bar')(2.0)
<MagicMock name='mock().method().other()()' id='...'>
>>> kall = call(1).method(arg='foo').other('bar')(2.0)
>>> kall.call_list()
[call(1),
 call().method(arg='foo'),
 call().method().other('bar'),
 call().method().other()(2.0)]
>>> m.mock_calls == kall.call_list()
True

Depending on how it is constructed,call the object can be a (positional parameter, keyword parameter) or (name, positional parameter, keyword parameter) tuple. This doesn't matter when you construct them yourself, but Mock.call_argsMock.call_args_list  objects in the  properties can be checked back to obtain the single parameter. Mock.mock_calls and call

 in  The object is a triple (name, positional parameters, keyword parameters).  and those constructed by you Mock.mock_calls The objects are (positional parameters, keyword parameters) tuples Mock.call_args_list and Mock.call_argscallcall

You can use their properties as "tuples" to obtain individual parameters for more complex introspection and assertion functions. The positional argument is a tuple (or an empty tuple if there are no positional arguments) and the keyword argument is a dictionary:

>>>

>>> m = MagicMock(return_value=None)
>>> m(1, 2, 3, arg='one', arg2='two')
>>> kall = m.call_args
>>> kall.args
(1, 2, 3)
>>> kall.kwargs
{'arg': 'one', 'arg2': 'two'}
>>> kall.args is kall[0]
True
>>> cold.kwargs ice cold[1]
True

>>>

>>> m = MagicMock()
>>> m.foo(4, 5, 6, arg='two', arg2='three')
<MagicMock name='mock.foo()' id='...'>
>>> kall = m.mock_calls[0]
>>> name, args, kwargs = kall
>>> name
'foo'
>>> args
(4, 5, 6)
>>> kwargs
{'arg': 'two', 'arg2': 'three'}
>>> name is m.mock_calls[0][0]
True

create_autospec

unittest.mock.create_autospec(specspec_set=Falseinstance=False**kwargs)

Create a mock object using another object as spec. The properties of the mock will use the corresponding properties on the spec object as its spec.

The parameters of the mocked function or method will be checked to ensure that they are called with the correct signature.

If spec_set is True then trying to set a property that does not exist in the spec object will raise . AttributeError

If a class is used as a spec then the return value of the mock (an instance of the class) will be this spec. You can use a class as a spec for an instance object by passing in instance=True . The returned mock will only be callable if the instance of the mock is a callable object.

create_autospec() also accepts any keyword arguments passed into the constructor of the mock being created.

See Autospec to learn how to use create_autospec() and patch() ’s autospec parameter to automatically set the spec.

Changed in version 3.8: create_autospec() will now return a  if the target is an asynchronous function AsyncMock.

ANY

unittest.mock.ANY

Sometimes you may need to set assertions about certain parameters in the call you want to simulate, but don't want to worry about other parameters or want Separate them from call_args and set up more complex assertions against them.

To ignore certain parameters you can pass in an object equal to any object . In this way, when calling assert_called_with() and assert_called_once_with() no matter what is passed in All parameters will be executed successfully.

>>>

>>> mock = Mock(return_value=None)
>>> mock('foo', bar=object())
>>> mock.assert_called_once_with('foo', bar=ANY)

ANY can also be used to compare with a call list like mock_calls :< /span>

>>>

>>> m = MagicMock(return_value=None)
>>> m(1)
>>> m(1, 2)
>>> m(object())
>>> m.mock_calls == [call(1), call(1, 2), ANY]
True

FILTER_DIR

unittest.mock.FILTER_DIR

FILTER_DIR is a module group variable that controls the way the mock object responds to dir() . The default value is True, which uses the filtering described below to display only useful members. If you don't like this filtering, or need to turn it off for diagnostic purposes, you should set mock.FILTER_DIR = False.

When filtering is enabled,dir(some_mock) will only display useful properties and will include any dynamically created properties that would not normally be displayed. If the mock is created using spec (of course it can also be autospec) then all existing properties will be displayed, even if they have not been accessed yet:

>>>

>>> dir(Mock())
['assert_any_call',
 'assert_called',
 'assert_called_once',
 'assert_called_once_with',
 'assert_called_with',
 'assert_has_calls',
 'assert_not_called',
 'attach_mock',
 ...
>>> from urllib import request
>>> dir(Mock(spec=request))
['AbstractBasicAuthHandler',
 'AbstractDigestAuthHandler',
 'AbstractHTTPHandler',
 'BaseHandler',
 ...

Many less useful (private members of Mock rather than the object being mocked) attributes that begin with underscores and double underscores From the results of a call to dir() on Mock Be filtered. If you don't like this behavior you can turn it off by setting the module-level switch FILTER_DIR :

>>>

>>> from unittest import mock
>>> mock.FILTER_DIR = False
>>> dir(mock.Mock())
['_NonCallableMock__get_return_value',
 '_NonCallableMock__get_side_effect',
 '_NonCallableMock__return_value_doc',
 '_NonCallableMock__set_return_value',
 '_NonCallableMock__set_side_effect',
 '__call__',
 '__class__',
 ...

You can also choose to use vars(my_mock) (instance member) and dir(type(my_mock)) (type member) to bypass mock.FILTER_DIR filter.

mock_open

unittest.mock.mock_open(mock=Noneread_data=None)

Create a mock instead of using the open() helper function. It applies both when open() is called directly or when used as a context manager.

The mock parameter is the mock object to be configured. If None (default), a MagicMock will be created for you, and its API will be restricted to standard File handling methods or properties.

read_data is for file processing read()readline() The string returned by the readlines() method. Calling these methods will fetch data from read_data until it is exhausted. The mocking of these methods is quite simplified: every time mock is called, read_data< a i=12> will start from scratch. If you need more control over the data you provide to your test code then you will need to customize this mock yourself. If that's not enough, some in-memory filesystem packages on PyPI can provide a more realistic test filesystem.

Changed in version 3.4: Added support for readline() and readlines() instead of returning it on each call. read_dataread() is changed to consume  support. The simulation of 

Changed in version 3.5: read_data will now be executed every time mock is reset when called.

Changed in version 3.8: Added __iter__() to the implementation so that iterative operations (such as in for loops) correctly consume read_data.

Use open() as a context manager - the best way to ensure that your file handling is closed properly and therefore very common:< /span>

with open('/some/path', 'w') as f:
    f.write('something')

The problem here is that even though you simulate a call to open() it is used as a context manager (and calls its open() a> . The object being returned methods) are __exit__() and __enter__()

It is very common and troublesome to simulate the context manager through MagicMock so a helper function is needed.

>>>

>>> m = mock_open()
>>> with patch('__main__.open', m):
...     with open('foo', 'w') as h:
...         h.write('some stuff')
...
>>> m.mock_calls
[call('foo', 'w'),
 call().__enter__(),
 call().write('some stuff'),
 call().__exit__(None, None, None)]
>>> m.assert_called_once_with('foo', 'w')
>>> handle = m()
>>> handle.write.assert_called_once_with('some stuff')

And for reading files:

>>>

>>> with patch('__main__.open', mock_open(read_data='bibble')) as m:
...     with open('foo') as h:
...         result = h.read()
...
>>> m.assert_called_once_with('foo')
>>> assert result == 'bibble'

automatic spec

Auto spec is based on the existing mock's spec feature. It limits the mock's API to that of the original object (spec), but it is recursive (lazy implemented) so the mock's properties only have the same API as the spec's properties. Otherwise moduled functions/methods have the same call signature as their original counterparts and therefore will raise a TypeError  if they are called incorrectly.

Before I start explaining how automatic spec works, let me explain why it is necessary.

Mock is a very powerful and flexible object, but it has two drawbacks when used to mock objects from the system under test. One of the flaws is specific to Mock 's API and the other is a common problem when using mock objects.

The first question is exclusive to Mock . Mock has two particularly useful assertion methods: assert_called_with() and assert_called_once_with().

>>>

>>> mock = Mock(name='Thing', return_value=None)
>>> mock(1, 2, 3)
>>> mock.assert_called_once_with(1, 2, 3)
>>> mock(1, 2, 3)
>>> mock.assert_called_once_with(1, 2, 3)
Traceback (most recent call last):
 ...
AssertionError: Expected 'mock' to be called once. Called 2 times.

Because mocks automatically create properties as needed and allow you to call them with any parameters, your assertions will fail if you write the wrong two assertion methods:

>>>

>>> mock = Mock(name='Thing', return_value=None)
>>> mock(1, 2, 3)
>>> mock.assret_called_once_with(4, 5, 6)  # Intentional typo!

Your tests will silently and incorrectly pass because of this typo.

The second problem is common in mock operations. If you refactor part of your code, such as changing the names of some members, etc., any part of the code is still using the old api  but its use Tests that are mocks instead of real objects will still pass. This means that even if your code is broken your tests may still all pass.

Note that this is one of the reasons why you need integration tests in addition to unit tests. Testing each part in isolation is all fine and smooth, but if you're not testing how your units "fit together" then there's still room for testing to find a lot of bugs.

mock already provides a feature that helps with this, called spec control. If you use a class or instance as a mock then you will only be able to access properties in the mock that only exist in the actual class. spec

>>>

>>> from urllib import request
>>> mock = Mock(spec=request.Request)
>>> mock.assret_called_with  # Intentional typo!
Traceback (most recent call last):
 ...
AttributeError: Mock object has no attribute 'assret_called_with'

This spec will only apply to the mock itself, so we still have the same problem for any method in the mock:

>>>

>>> mock.has_data()
<mock.Mock object at 0x...>
>>> mock.has_data.assret_called_with()  # Intentional typo!

Auto spec solves this problem. You can pass autospec=True to patch() / patch.object()  Or use the create_autospec() function to create a mock with spec. If you pass the autospec=True argument to patch() then the replaced object will be used as the spec object. Because spec control is executed "lazily" (spec is not created until the properties in the mock are accessed) even very complex or deeply nested objects (such as the need to import a module that itself imports multiple modules) You can also use it without much performance penalty.

Here is an example of a practical application:

>>>

>>> from urllib import request
>>> patcher = patch('__main__.request', autospec=True)
>>> mock_request = patcher.start()
>>> request is mock_request
True
>>> mock_request.Request
<MagicMock name='request.Request' spec='Request' id='...'>

You can see that request.Request has a spec. The constructor of request.Request accepts two parameters (one of which is self). If we try to call it incorrectly this will result in:

>>>

>>> req = request.Request()
Traceback (most recent call last):
 ...
TypeError: <lambda>() takes at least 2 arguments (1 given)

The spec will also apply to the instantiated class (i.e. the return value of the mock with the return value of spec ):

>>>

>>> req = request.Request('foo')
>>> req
<NonCallableMagicMock name='request.Request()' spec='Request' id='...'>

Request The object is a non-callable object, so the return value of instantiating our mocked request.Request is a non-callable mock. With this spec any spelling issues in our assertions will raise the correct error:

>>>

>>> req.add_header('spam', 'eggs')
<MagicMock name='request.Request().add_header()' id='...'>
>>> req.add_header.assret_called_with  # Intentional typo!
Traceback (most recent call last):
 ...
AttributeError: Mock object has no attribute 'assret_called_with'
>>> req.add_header.assert_called_with('spam', 'eggs')

In many cases you will simply add autospec=True to your existing patch() Problems caused by spelling errors and API changes can be prevented during the call.

In addition to using patch() autospec There is a create_autospec() that can directly create a mock with automatic spec:

>>>

>>> from urllib import request
>>> mock_request = create_autospec(request)
>>> mock_request.Request('foo', 'bar')
<NonCallableMagicMock name='mock.Request()' spec='Request' id='...'>

This is not without its drawbacks and limitations, which is why it is not the default behavior. In order to know what properties are available on the spec object, autospec must introspect the spec (access its properties). When you iterate over properties on the mock the corresponding iteration on the original object will also be done under the hood. If any of your spec objects have characteristic properties or descriptors that trigger code execution you may not be able to use autospec. On the other hand it is better to design your objects to be able to perform introspection safely 4 .

A more serious problem is that instance properties are often created in the __init__() method but do not exist at all in the class. autospec Unable to obtain dynamically created properties, which limits the api to visible properties.

>>>

>>> class Something:
...   def __init__(self):
...     self.a = 33
...
>>> with patch('__main__.Something', autospec=True):
...   thing = Something()
...   thing.a
...
Traceback (most recent call last):
  ...
AttributeError: Mock object has no attribute 'a'

There are a few different ways to solve this problem. The easiest, but somewhat annoying, way is to simply set the required properties after the mock is created. Just because autospec just does not allow you to get properties that do not exist on the spec but does not prevent you from setting them:

>>>

>>> with patch('__main__.Something', autospec=True):
...   thing = Something()
...   thing.a = 33
...

spec and autospec both have stricter versions  It does prevent you from setting properties that don't exist. This is also useful if you want to ensure that your code can only set valid properties, but obviously it will prevent this specific use case:< /span>

>>>

>>> with patch('__main__.Something', autospec=True, spec_set=True):
...   thing = Something()
...   thing.a = 33
...
Traceback (most recent call last):
 ...
AttributeError: Mock object has no attribute 'a'

The best way to solve this problem is probably to add the class attribute as the default value for the instance attribute initialized in __init__() . Note that if you only set default properties in __init__() then it will also be faster to provide them via class properties (which will of course be shared between instances). For example

class Something:
    a = 33

This brings up another problem. It is common practice to provide default values ​​ None for those members that will later become objects of different types. None is useless as a spec because it will give you no access to any any properties or methods. Since None as a spec will  never be of any use, and it is possible to specify something usually of another type members, so autospec will not use spec for members set to None . They will be normal mocks (well - should be MagicMocks):

>>>

>>> class Something:
...     member = None
...
>>> mock = create_autospec(Something)
>>> mock.member.foo.bar.baz()
<MagicMock name='mock.member.foo.bar.baz()' id='...'>

If you don't feel like modifying your production classes to add default values ​​there are other options. One of them is to simply use an instance instead of a class as spec. Another option is to create a subclass of the production class and add default values ​​to the subclass without affecting the production class. Both options require you to use a replacement object as spec. Thankfully patch() supports this - you can simply pass in the replacement object as autospec< /span> Parameters:

>>>

>>> class Something:
...   def __init__(self):
...     self.a = 33
...
>>> class SomethingForTest(Something):
...   a = 33
...
>>> p = patch('__main__.Something', autospec=SomethingForTest)
>>> mock = p.start()
>>> mock.a
<NonCallableMagicMock name='Something.a' spec='int' id='...'>

4

This only applies to classes or instantiated objects. Calling a mocked class to create a mock instance  will not  create a real instance. Only property lookups — and calls to dir() — are performed.

Wrap mock

unittest.mock.seal(mock)

Wrapping will disable automatic mock creation when accessing a property of the wrapped mock or any of its properties that have been recursively mocked.

If a mock instance with name or spec is assigned to a property it will not be processed in the packet chain. This prevents people from wrapping fixed parts of the mock object.

>>>

>>> mock = Mock()
>>> mock.submock.attribute1 = 2
>>> mock.not_submock = mock.Mock(name="sample_name")
>>> seal(mock)
>>> mock.new_attribute  # This will raise AttributeError.
>>> mock.submock.attribute2  # This will raise AttributeError.
>>> mock.not_submock.attribute2  # This won't raise.

New features in version 3.7.

Guess you like

Origin blog.csdn.net/TalorSwfit20111208/article/details/135025452