What is the difference between Mock and Spy?
Sometimes as developers, we need to define how to design a write the software based on business requirements.
Although the decision about the test approach is inside this bundle. When talking about UT (unit tests) the use of Mock and Spy are widely used and in this article, I bring examples and definitions of each one.
TLDR
Mock — Mock object replace mocked class entirely, returning recorded or default values. You can create mock out of “thin air”. This is what is mostly used during unit testing.
Spy — When spying, you take an existing object and “replace” only some methods. This is useful when you have a huge class and only want to mock certain methods (partial mocking)
Too long read :)
First of all, let's see each one separately and go deeper into examples.
1. Definition
1.1. Mock
From the Cambridge dictionary [2] are these definitions
- to laugh at someone, often by copying them in a funny but unkind way
- to make something appear stupid or not effective:
- not real but appearing or pretending to be exactly like something: (I like this definition, is the behavior used into the tests 👌).
From Wikipedia[3] this is the definition
- In object-oriented programming, mock objects are simulated objects that mimic the behavior of real objects in controlled ways, most often as part of a software testing initiative. A programmer typically creates a mock object to test the behavior of some other object, in much the same way that a car designer uses a crash test dummy to simulate the dynamic behavior of a human in vehicle impacts. The technique is also applicable in generic programming.
1.2. Spy
Now is time to check the Spy definition using the same resources.
From Cambridge dictionary[2] these definitions
- a person who secretly collects and reports information about the activities of another country or organization
- to see or notice someone or something usually when it involves looking hard:
- to see or notice someone or something (I really liked it 👌)
From the site Java Point this is the definition for Spy
- Spies are known as partially mock objects. It means spy creates a partial object or a half dummy of the real object by stubbing or spying the real ones. In spying, the real object remains unchanged, and we just spy some specific methods of it. In other words, we take the existing (real) object and replace or spy only some of its methods.
2. Domain
The domain to explain the Mock and Spy is below. To explain not all methods will be implemented.
3. Examples
3.1. Service
This is the Service. The methods save and delete will be tested.
3.2. Mock
⚠️ Mock replace the entire class.
3.2.1. Save
In this test the behavior is defined by the when(mock). Doesn't matter if the class is performing a validation, database communication, etc nothing will be called.
3.2.2. Delete
In a real world, if the delete method is called the exception UnsupportedOperationException will be thrown, but we are using Mock, but in this case the call will work properly.
Pay attention to the line 6, the verify will verify the Mock, the real method will not be called.
3.2. Spy
On the other hand, using Spy, the method will be executed and the method will be really tested.
3.2.1. Save
In this first test, the only mocked class is the repository, since at this point the repository should be tested using an IT (Integration Test).
3.2.2. Delete
Using Spy, the method will be called and an exception will be thrown, as expected 😃
4. Conclusion
Both Mock and Spy are powerful and should be used to guarantee that your system has the correct test and when a method should be tested, please use Spy and Mock any dependency.
Other point is increase the code coverage, and sometimes the use of Mock to increase this indicator won't guarantee a good tested system.
The complete code is available in my GitHub account https://github.com/luizgustavocosta/mock-spy
If you like this article, share in your social media :)
5. References
[1] — https://pixabay.com/illustrations/man-gallery-museum-observer-6477113/