4
4
.
.
2
2
M
M
o
o
c
c
k
k
i
i
t
t
o
o
I
I
n
n
f
f
o
o
Following tutorials show how to use Mockito. (inside JUnit Tests)
Mockito is used to Mock Dependencies (Classes and Methods that are called by the Method being tested)
first you Mock Class (you need to Mock Class in order to be able to Mock its Methods)
then you Mock Methods (of Mocked Class)
To Mock Method means to specify return value for specific Input Parameters.
To Mock Method first you need to Mock Class to which this Method belongs to.
Class can be Mocked using either @Mock or @Spy.
In both cases Mocked Method returns what is defined by Mockito and not what the actual implementation would return.
Mock Object
@Mock PersonRepository personRepositoryMock;
@Spy PersonRepository personRepositoryMock;
Inject Mocked Objects (in place of @Autowired)
@InjectMocks MyController myController;
Mock Method
when (personRepositoryMock.getPersonById(1)).thenReturn(new Person(1, "Susan", 50));
given(personRepositoryMock.getPersonById(1)).willReturn(new Person(1, "Susan", 50)); /Alias for when()
doReturn(new Person(1, "Susan", 50)).when(personRepositoryMock).getPersonById(1); //Alternative for when()
@
@
M
M
o
o
c
c
k
k
v
v
s
s
@
@
S
S
p
p
y
y
[
[
R
R
]
]
The difference is that with
@Mock Real Method is never called
@Spy Real Method is always called & executed but return value is intercepted & Mocked Value is returned instead
We could say that
@Mock creates fully Mocked Object (Object only has Mocked Methods defined by Mockito)
@Spy creates partially Mocked Object (Object has combination of Real and Mocked Methods)
The other subtle difference is that with @Spy Real Methods are always called - calls to Real Methods are not blocked.
If Method was Mocked it will return what was defined by Mockito after it gets executed.
If Method was not Mocked it will return what was defined by its actual implementation.
Syntax
//MOCK DEPENDENCY CLASS (choose @Mock or @Spy)
@Mock PersonRepository personRepositoryMock;
@Spy PersonRepository personRepositorySpy;
//INJECT MOCKS (into Class being tested where @autowired is used)
@InjectMocks MyController myController;
//MOCK METHOD OF DEPENDENCY CLASS (Methods are mocked in the same way for both @Mock and @Spy)
when(personRepositoryMock.getPersonById(1)).thenReturn(new Person(1, "Susan", 50));
when(personRepositorySpy .getPersonById(1)).thenReturn(new Person(1, "Susan", 50));
@
@
M
M
o
o
c
c
k
k
@Mock creates fake Object without any Methods except those that you introduce through when() and doReturn().
In @Mock Object default behavior of the Method is to do nothing.
@Mock is used for Functional Testing - to test functionality of a component in isolation from other components.
This means that during tests Mocked Methods are called instead of real ones.
Calls to Mocked Methods are intercepted by Mockito which then returns whatever we specify.
This way we can test how tested Method would behave when Dependent Methods return certain values.
Such approach is useful during parallel development of interdepended components.
Each developer can test his component by Mocking dependent components that are still under development.
@Mock
For instance if we are testing Endpoint that calls Repository, then we would Mock Repository to return specific value.
That way we can test Endpoint's functionality without having access to the actual Repository or the underlying Database.
And we can also test how Endpoint will behave upon receiving different values from the Repository without having to
adjust Database to actually return these values.
Example
Tested
Object
@Mock
Object
Dependency
Object
@Test Method
(Call Method)
Mocked Method
MyController
Mocked
Respository
Respository
Tomcat
H2
JUnit
@Test Method
Tested Method
Dependency
Mocked Dependency
@
@
S
S
p
p
y
y
@Spy creates Wrapper Object around real/existing Object that has its own working Methods.
Then you use when() or doReturn() to change return value just for some of those Methods.
In @Spy Object default behavior of the Method is the one implemented by the Application.
@Spy is used for Integration Testing - to test how your component interacts/integrates with other components.
So with @Spy you can test one component at the time by Mocking calls to those other components not being tested.
@Spy
Tested
Object
@Spy
Object
Dependency
Object
@Test Method
(Call Method)
Mocked Method 1
Real Method 1
Real Method 2
Real Method 2