Reputation: 2274
I am using Mockito to mock a method in the same class for which I am writing test. I have seen other answers on SO (Mocking method in the same class), but probably I am misunderstanding them, since I running into issues.
class Temp() {
public boolean methodA(String param) {
try {
if(methodB(param))
return true;
return false;
} catch (Exception e) {
e.printStackTrace();
}
}
}
My Test method:
@Test
public void testMethodA() {
Temp temp = new Temp();
Temp spyTemp = Mockito.spy(temp);
Mockito.doReturn(true).when(spyTemp).methodB(Mockito.any());
boolean status = temp.methodA("XYZ");
Assert.assertEquals(true, status);
}
I however get the expection printed out because definition of methodB gets executed. My understanding is definition of methodB would get mocked by using spyTemp. However that does not appear to be the case.
Can someone please explain where I am going wrong?
Upvotes: 64
Views: 133271
Reputation: 3918
The first issue is that you have to use spyTemp object to expect something from Mockito. Here it is not the same as test. spyTemp
is wrapped by the Mockito object temp
.
Another issue is that you stub only methodB()
, but you are trying to run methodA()
. Yes in your implementation of methodA()
you call methodB(), but you call this.methodB()
, not spyTemp.methodB()
.
Here you have to understand that mocking would work only when you call it on the instance of temp
. It's wrapped by a Mockito proxy which catches your call, and if you have overriden some method, it will call your new implementation instead of the original one. But since the original method is called, inside it you know nothing about Mockito proxy. So your "overriden" method would be called only when you run spyTemp.methodB()
This should work:
Mockito.doReturn(true).when(spyTemp).methodB(Mockito.any());
boolean status = spyTemp.methodA("XYZ");
Upvotes: 67
Reputation: 27986
Note the following from Mockito documentation:
Mockito does not delegate calls to the passed real instance, instead it actually creates a copy of it. So if you keep the real instance and interact with it, don't expect the spied to be aware of those interaction and their effect on real instance state. The corollary is that when an unstubbed method is called on the spy but not on the real instance, you won't see any effects on the real instance.
This is referring specifically to your situation. You keep a reference to temp
and then call its methodA
. Mockito is not spying on that instance at all; it's spying on spyTemp
. So the normal methodB
is called.
Note that you should avoid partial mocks altogether for new code.
Upvotes: 9
Reputation: 8095
You created a spy and mocked methodB()
. That is correct! But you called methodA()
on the original object. To get the correct result call it on the spy
boolean status = spyTemp.methodA("XYZ");
Upvotes: 26