Why do I need a mock
Suppose the system now has two models A and B, where a relies on B (for example, A,b is a function, a function body calls B functions), but B is not completed, or is not in control at this time, and then need to test the function of a, you need to use mock object, simulate a fake Fake_b module , although the Fake_b module is fake, we can customize it by customizing its behavior so that he can look like the function of the "B" module and make a dependent fake_b to test the function of a. At the same time, because the fake_b is completely controllable, in addition to the properties of B can be customized, return value, you can also test the use of B module.
In Python, mocks and unittest.mock can be used to produce such mock objects. Introduction to Usage
First you need to create a mock object
>>>from Mock Import Magicmock
You can then set its return value by Return_value, and when you call the mock object, the return value can be of any type, variable, function, class object.
>>>fake_obj.return_value = ' This is a mock object '
>>>fake_obj ()
' It is a mock object '
You can also specify its side effects by Side_effect, which is when you call the mock object as a function called, or you can choose to throw an exception to test the error state of the program.
>>>def b (): .. print ' This is B '
...
>>>fake_obj.side_effect = b
>>>fake_obj () This is
b
>>>fake_obj.side_effect = Keyerror (' This is B ')
>>>fake_obj () ...
Keyerror: ' This is B '
You can also extend a mock based on an object base, allowing the mock to get all of the properties and methods of base (but only the interfaces are the same, not implemented), and throw attributeerror when you call properties and methods that do not belong to base. This requires that when you create a mock object, you specify in the spec parameter that the preceding return value and side effects can also be specified at creation time.
>>>class B: ... def __init__ (self):
... SELF.A = ' A '
...
>>>b = B ()
>>>fake_obj = Magicmock (b)
<magicmock spec= ' B ' id= ' 4370614160 ' >
>>>fake_obj.a '
a '
>>>fake_obj.b
Attributeerror:mock object has no attribute ' B '
It is also important to emphasize that if you want to simulate an object instead of a function, you can add properties and methods directly to the mock object, and each added attribute is a mock object, that is, you can configure these properties and can be recursively defined.
>>>fake_obj.fake_a.return_value = ' This are fake_obj.fake_a '
>>>fake_obj.fake_a ()
' This is Fake_obj.fake_a '
After a mock object is configured with a mock object for testing, the module is tested in a ' action-assertion ' way, which runs first and then tests with assertions. For example, you can test whether a mock object is invoked, how many times it is invoked, how it is invoked, and so on, and the mock object itself provides a rich assertion method, which is provided in an official document with a detailed description.
>>>fake_obj = Magicmock (return_value = 1)
>>>fake_obj.assert_called ()
AssertionError: Expected ' None ' to have been called.
>>>fake_obj ()
>>>fake_obj.assert_called ()
>>>
>>>fake_obj ( 1,2,3,key=1)
>>>fake_obj.assert_called_with (1,2,3,key=1)
>>>
The mock library also provides a patch function to simplify the substitution of mock objects for the original object. Patch can be used as an adorner or context manager, which means that in the decorated function and context Manager, the corresponding class is replaced with a mock object.
>>>from mock import Patch
>>> @patch (' __main__. SomeClass ')
... def function (Normal_argument, mock_class):
... Print (Mock_class is SomeClass)
...
>>>function (None)
True
reference materials
Official Documents Https://docs.python.org/3/library/unittest.mock.html