Mock With Mockito
Contents
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.
Why mock?
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 AnotherObject.method()
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 AnotherObject.method()
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.
Use Mockito
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(MockFeatures<T>)
and newInstance(Class<T>)
methods.
generateMockClass
method uses a third-part library ByteBuddy to generate
class.
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 generateMockClass
.
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).
Author Wenfeng
LastMod 2016-05-13