What is Mock in python?...
Why do we use Mock in Python??
Where to use Mock in python???
--------------------------------------------------------------------------------------------------------------------------
Why do we use Mock in Python??
Where to use Mock in python???
--------------------------------------------------------------------------------------------------------------------------
Reasons to Mock
There are times when a test resource is either unavailable or unsuitable. Perhaps the resource is being developed in parallel with the test subject. It may then be incomplete or too unstable to be reliable.
The resource may be too costly. If the resource is a third-party product, its high price tag can disqualify its use for testing. Setting up the resource might be complex, taking up hardware and time that could be used elsewhere. If the resource is a data source, setting up its data set, one that mimics real-world content, can get tedious.
The resource may simply be unpredictable. A good unit test has to be repeatable, allowing you to isolate and identify a fault. But the test resource might give out stochastic results, or it might have widely varying response times. And as a result, you end up glossing over a potential showstopper.
These are some of the reasons why you might want to use a mock in place of a test resource. A mock can present the same set of method interfaces as the resource to the test subject. But a mock is easier to setup, easier to manage. It can present the test subject the same method interfaces as the actual test resource. It can deliver deterministic results, and it can be customize to suit a particular test. And it can be easily updated to reflect changes in the actual resource.
Of course, mocks are not without issues. Designing an accurate mock is difficult, especially if you have no reliable information on the test resource. You can try and find an open-source match, or you can make a guesstimate on the resource's method interface. Whichever you choose, you can update the mock easily later on, should you get more detailed information on the preferred resource.
Too many mocks can complicate a test, making it harder for you to track down a failure. Best practice is to limit a test case to one or two mocks, or use separate test cases for each mock/subject pairing.
Mocks versus Stubs versus Fakes
A mock is not the only way to mimic a test resource. Solutions like a stub or a fake are just as capable of the same service. So, how does a mock compare against these two? Why choose a mock over a stub or a fake?
Consider the stub: A stub presents a set of method interfaces to the test subject, the same set the subject would see in an actual test resource. When the test subject calls a stub method, the stub may respond with a predetermined set of results. It may raise an error or exception, also predetermined. A stub may track its interactions with the test subject, but it performs no tasks outside the narrow scope of its programming.
A fake also presents a set of method interfaces and tracks its interactions with the test subject. But unlike a stub, a fake actually processes input data from the test subject and produces results based on that data. In short, a fake is a functional, but non-production version of the actual test resource. It lacks the checks and balances found in resource, it uses simpler algorithms, and it seldom, if ever, stores or transports data.
With fakes and stubs, you can test if the test subject called the right method with the right input. You can test how the subject handles the result and how it reacts to an error or exception. These tests are known as state verification. But what if you want to know if the test subject called the same method twice? What if you want to know if it called several methods in the proper order? Such tests are known as behavior verification, and to do them, you need mocks.
To Mock with Python
The Mock module is what you use to create and manage a mock object on Python. This module is the brainchild of Michael Foord, and it is a standard module on Python 3.0. For Python 2.4 to 2.7, however, you have to install the module yourself. You can get the latest version of the Mock module (1.0.1) from the Python Package Index website.
The typical test setup has at least two parts. First, there is the test subject (red), the focus of the test. It can be a method, module, or class. It may or may not return a result, but it can raise an error or exception depending on input data or internal state (Figure 1).
Second is the test case (grey), which runs alone or as part of a suite. It prepares the test subject, as well as any data or resources needed by the subject. It runs one or more test routines and checks how the test subject behaves in each test. And it collects the test results and presents them in a concise, readable format.
Now, some test subjects need one or more resources (green) in order to function. These resources may be another class or module, or even an independent process. Whatever their nature, test resources are functional code. Their role is to support the test subject, but they are not the focus of the test.
The Mock module provides a handful classes on which to base your mock object. There is even a patch mechanism for altering the mock on the fly. But for now, our focus is on one class: the
Mock
class.
Figure 2 shows the basic structure of the
Mock
class (green). It derives from two parent classes:NonCallableMock
and CallableMixin
(grey). NonCallableMock
defines the routines needed by the mock object. It overrides several magic methods, giving them default behaviors. And it supplies the assert routines for tracking the mock's behavior. As for CallableMixin
, it updates those magic methods that make a mock object callable. In turn, both parents derive from theBase
class (red), which declares the properties needed by the mock object.Preparing to Mock
The
Mock
class has four sets of methods (Figure 3). In the first set is the class constructor, which takes up to six optional and labeled arguments. The diagram shows the four arguments you will use most often
.