What is Mocking in Testing?
It is just an introduction for what is mocking and why Mocking is used.
Let’s explore!
In simple English, Mocking is make a replica or imitation of something.
We use mocking in unit testing. A object that you want to test may have dependencies on other complex objects. To isolate the behavior of the object you want to test you replace the other objects by mocks that simulate the behavior of the real objects. So in simple words, mocking is creating objects that simulate the behavior of real objects.
In unit testing we want to test methods of one class in isolation. But classes are not isolated. They are using services and methods from other classes. So in that situation, we mock the services and methods from other classes and simulate the real behavior of them using some mocking frameworks and use that mocked methods and services to do unit testing in isolation. This is where Mocking frameworks come into play.
There are a lot of frameworks used for mocking in unit testing such as PowerMock, Mockito, EasyMock, etc.
General Types of Mocking frameworks
- Proxy based ( eg: EasyMock, JMock, Mockito)
- Byte code Manipulation / Classloader remapping ( eg: jMockit, PowerMock)
What is Proxy based Mocking? How it works?
A proxy is just an object which will be used instead of the original object. If a method of the proxy object is called than the proxy object can decide what it will do with this call:
- delegate it to the original object
- handles the call itself
A proxy doesn’t require an instance of an interface/class if the proxy handles all method invocations itself.
Consider,
Mockito.mock(Foo.class)
This code just creates a proxy object for the Foo class.
Limits of Proxy
There are a few important restrictions to the proxies. It’s not possible to:
- intercept static method calls
- intercept private method calls
- intercept final method calls
- build a proxy for a final class
What is Classloader remapping based Mocking?
What happens is that, you tell the class loader to remap the reference to the class file it loads.
So let’s say that I have a class Foo class with the corresponding .class file called Foo.class and I want to mock it to use MyMock instead. By using this type of mock objects, you will actually remap in the classloader the reference from Foo.class to MyMock.class.
This allows you to be able to mock objects that are created by using thew new operator.
This approach provides more power than the proxy object approach.
Using PowerMock or other mocking frameworks based on class loader remapping , we can overcome the limits of proxy based mocking.
Since Mock objects are a very valuable tool in testing, they provide you with the ability to test what you write without having to address dependency concerns.