>>>>>>>>>>>>>>>>>>>>>The actual application of the content is insufficient and needs to be supplemented
3. MagicMock -- it implements some magic method s built in mock. Those that need to be manually defined in mock can be named directly and called with magiclock
Magic Mock, a subclass of mock, creates all magic methods of mock while creating the Magic Mock object. It is used to simulate the python protocol method, which is used to replace the container or object that implements the python protocol.
The magic method index of mock is recorded as__ X__ Mock built-in method.
Magic's method will not pre create relevant methods during Mock, but need to be created manually; MagicMock can pre create all magic methods, so it can be used directly.
* If you use the spec keyword argument to create a mock then attempting to set a magic method that isn't in the spec will raise an AttrributeError.
If you use the spec keyword when creating a mock object and use the magic method that the spec keyword does not have, an attribute error will be reported-- Magic of mock needs to be created manually, not pre created like magiclock.
* MagicMock is a subclass of Mock with default implementations of most of the magic methods. You can use MagicMock without having to configure the magic methods yourself.
* If you use the spec or spec_set arguments then only magic methods that exist in the spec will be created.
There are two variants of MagicMock: MagicMock and NonCallableMagicMock
reference resources: https://docs.python.org/3/library/unittest.mock.html#magicmock-and-magic-method-support , magic method supported by mock
from unittest.mock import Mock from unittest.mock import MagicMock class tc(): tl1 = [] def __init__(self): pass def tc1(): return "tc1" ## mock mock = Mock() ## mock spec mock.mock_add_spec(tc) mock.tl1 mock.tc1 mock.tl2 # spec:tc, no TL2 definition, error reported; AttributeError: Mock object has no attribute 'tl2' #### mock's__ iter__magic method cannot be pre created and needs to be created manually # mock.__iter__ # raise AttributeError(name), AttributeError: __iter__ mock.__iter__ = mock.return_value() print(mock) ## magicmock magicmock = MagicMock() #### The pre created magic method can be called directly magicmock.__iter__ print(magicmock) >>> mock.__len__ <function NonCallableMock.__setattr__.<locals>.<lambda> at 0x00FD2C00> >>> magicmock.__len__ <MagicMock name='mock.__len__' id='91021680'> >>> magicmock.__len__() 0 >>>
4. PropertyMock - class unittest.mock.PropertyMock(*args, * * kwargs) -- propertymock sets a property, method, or description in an alternative class
mock instances are used as attributes or other descriptions of classes. They are provided when used__ get__ () and__ set__ () method defines its call return value.
Object calls mock to get an instance of PropertyMock without parameters, and calls the value setting of mock.
from unittest.mock import PropertyMock pmock = PropertyMock() class pc1: def __init__(self, v1): self.v1 = v1 def p1(self): print("PropertyMock") p = pc1(5) # instance class, variable: 5 print(p.v1) # call class variable, return: 5 p.p1() # call class method,return: PropertyMock pmock.return_value = 'return value' p.v1 = pmock print(p.v1) # <PropertyMock id='72342288'> type(p).v1 = pmock # PorpertyMock as class property # type(p) call __set__(self, obj, val) and __get__(self, obj, obj_type) method print(p.v1) # call class variable, return PropertyMock instatnce return_value pmock.return_value = p.p1 type(p).p1 = pmock print(p.p1) # <PropertyMock id='79380080'> p.p1() # PropertyMock type(p).p1 = pmock # PorpertyMock as class property # type(p) call __set__(self, obj, val) and __get__(self, obj, obj_type) method print(p.p1) # call class method, retrun PropertyMock instatnce return_value p.p1() # class initial value replace by PropertyMock # TypeError: 'str' object is not callable
5. AsyncMock -- New in version 3.8.
Mock upgrade, which allows you to simulate asynchronous functions
The asynchronous version of MagicMock. When the object is recognized as an asynchronous function, the AsyncMock object is executed, and the function call result can be suspended. -- await asynchronous wait, the operation on the running thread when the program is running in order to perform some special operations.
When mock() is an asynchronous function, side will be returned after asynchronous wait_ Effect or return_value: define side_ Side returned when effect_ Effect, otherwise return_value.
If the output is an asynchronous function, the asynchronous function simulated when the simulated object is called is the asynchronous function itself.
from unittest.mock import AsyncMock, Mock, asyncio class ac: def sync(): print('sync') async def a_sync(i): print(i) amock = AsyncMock(ac) # The mock method (mock, magiclock, asynclock) of class automatically detects whether its calling method is synchronous or asynchronous print(amock.sync) # <MagicMock name='mock.sync' id='2810946685872'> print(amock.a_sync) # <AsyncMock name='mock.a_sync' id='2810946742160'> async def await_sync(i): await i print(i) i = amock() print(amock.assert_awaited()) # None ##amock.called # AssertionError: Expected mock to have been awaited. asyncio.run(await_sync(i)) # <coroutine object AsyncMockMixin._execute_mock_call at 0x0000020DF0146440> ##print(amock.assert_not_awaited()) # AssertionError: Expected mock to not have been awaited. Awaited 1 times. print(amock.assert_awaited()) # None amock = AsyncMock(await_sync) amock() # RuntimeWarning: coroutine 'AsyncMockMixin._execute_mock_call' was never awaited
Method | explain |
assert_awaited() | Assert that mock waits asynchronously at least once |
assert_awaited_once() | Assert that mock waits asynchronously only once |
assert_awaited_with(*args, **kwargs) | Assertion last waited asynchronously with a specific parameter |
assert_awaited_once_with(*args, **kwargs) | Assert that mock waits asynchronously once with a specific parameter |
assert_any_await(*args, **kwargs) | Assert any asynchronous wait |
assert_has_awaits(calls, any_order=False) | Assert that mock waits asynchronously with a specific call |
assert_not_awaited() | Assert that mock never waits asynchronously |
reset_mock(*args, **kwargs) | Reset mock settings |
await_count | Asynchronous wait times |
await_args | Asynchronous wait parameter |
await_args_list | Asynchronous waiting parameter list |
6. patchers ?
Decorator: function objects are passed as arguments.
Patch decorator is used to wrap objects within a certain functional range. It is convenient to use mock objects to temporarily replace classes in specific modules. The default patch creates an alternative class for MagicMock.
patch(), function, class or content management, used to patch new objects.
unittest.mock.patch(target, new=DEFAULT, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, **kwargs)
>>Target: refers to a class method; Referenced from the called patch(), when the @ decorator function is executed, 'package module. ClassName'
>> patch(). start / patch().stop: mock the object through the patch () method
from unittest.mock import Mock, patch import pmock # self define class patcher = patch("pmock.func",spec='patcher',first='1') # define target: pmock.func mock= patcher.start() # mock path() object print(mock.first) # 1: call mock methoc patcher.stop() def tp(): print("patcher test") @patch("pmock.func",spec='patcher',first="patcher check first") def test(f): tp() # patcher test print(f.first) # patcher check first print(pmock.func) # <NonCallableMagicMock name='func' spec='str' id='3121040519120'> assert pmock.func == "patcher check" # AssertionError test()
patch | explain |
object | patch object properties |
dict | patch dictionary type |
multiple | Name multiple patcher s in one call |
start | Using patch, put the patch in place |
stop | undo it |
7. Helper
Helpers | explain |
sentinel | (sentinel) a simple method that provides a specific unique object for testing, and a method that provides a specific parameter or return value to make the return information readable |
DEFAULT | The pre created sentinel defines the normal return value |
call | Implement simple assertion on mock method call: call_args, call_args_list, mock_calls |
create_autospec | Create a new mock object with another object as a spec. the mock object uses the properties of the spec object by default? |
ANY | Complex assertions that achieve a specific purpose, regardless of parameters |
FILTER_DIR | Module level variable, which is used to control and filter the display content of dir() method of mock object? |
mock_open | mock open() method instead of open() method? |
Autospeccing | Based on the spec feature, limit the mock api of the initial object? |
Sealing mocks | seal(). When the properties of the accessed mock object are recursive by seal or properties, sell is used to prohibit the automatic creation of mock objects? |
from unittest.mock import Mock, sentinel, call, MagicMock, ANY class chelp: def __init__(self): pass def pval(self): print("this is helper") ch = Mock(spec='helper', name='chelper', return_value='this test',DEFAULT='default') # sentinel / DEFAULT print(ch.DEFAULT) # default ch.DEFAULT=sentinel.DEFAULT print(ch.DEFAULT) # sentinel.DEFAULT # call(*args, **kwargs) ch(1,a='a') print(ch.call_args_list == [call(1,a='a'),call()]) # False ch() # call mock print(ch.call_args_list == [call(1,a='a'),call()]) # True # call_list() mch = MagicMock() mch(1).method(2).other(3)(4,5) tcall = call(1).method(2).other(3)(4,5) print(tcall.call_list()) ''' [call(1), call().method(2), call().method().other(3), call().method().other()(4, 5)] ''' print(mch.mock_calls == tcall.call_list()) # True # ANY print(mch.mock_calls == [call(1),call(2),ANY]) # False mch.__init__() mch(1) mch(2) mch(3) print(mch.mock_calls == [call(1),call(2),ANY]) # True