Unit test takes an important role in software development, which ensures the code quality. Mockito is an open-source mocking framework for unit tests in Java. After trying, I found it very nice and easy to use, so this blog aims to introducing Mockito to you.
Mock means using a fake thing instead of the original one to help us test, but why do we need that?
Martin Fowler’s article Mocks Aren’t Stubs makes a lot sense explainning why.
Different test/thinking styles
The classic test case uses a state verification style, which means:
for exampel, if all goes well our SUT(subject under test) will call another Object’s method
AnotherObject.method() for example), so we’ll run our SUT and test whether
returns the expected value. If it does returns the expected value, the test passes.
That is the classic and traditional state verification style. But we can alse choose a different
test style, we call it behavior verification style.
We know that our SUT passes if it calls
AnotherObject.method(), and whether
returns expected values or not is not our responsibility and we don’t care about it! So the idea is
to verify whether the
AnotherObject.method() is called or not.
Isolated and clean code
The second reason we need to mock is more fundamental. Usually
AnotherObject.method() is not that
easy to run, perhaps it depends tough environment like internet connection, database connection ,etc.
So instead of really calling the method, we call our mocked method and just verify the call or verify its stubbed
return values, all is done.
Mockito is very easy to use.
You can mock and verify the interactions like
And stub method calls
How can Mockito mock an object
Mockito can mock whatever objects you own, I’m curious about how it works, and after going through some source code, it’s much clearer to me.
Here’s the flow of its calls.
The fundamental parts are
generateMockClass method uses a third-part library ByteBuddy to generate
Byte Buddy is a code generation library for creating Java classes during the runtime of a Java application and without the help of a compiler. To generate a class is just like:
The class we get is the child class of the class we want to mock(T).
Then in the
newInstance method, Mockito uses another third-part libray Objenesis to
initiate a new object of the class we get from
Why Mockito uses a libray to initaite object rather than initaite it directly? Because the class we get extends
the realy class we want to mock, if we
new it directly, the real class will be newed, which conflicts the
purpose of using Mock. Instead, by using Objenesis, only the child class will be newed.
So now the mock object has been created, and through the process we understand why Mockito can’t mock private or static method(because the child class can’t extends parent’s private/static methods).