I'm using Mockito in some tests.
I have the following classes:
class BaseService {
public void save() {...}
}
public Childservice extends BaseService {
public void save(){
//some code
super.save();
}
}
I want to mock only the second call (super.save
) of ChildService
. The first call must call the real method. Is there a way to do that?
No, Mockito does not support this.
This might not be the answer you're looking for, but what you're seeing is a symptom of not applying the design principle:
If you extract a strategy instead of extending a super class the problem is gone.
If however you are not allowed to change the code, but you must test it anyway, and in this awkward way, there is still hope. With some AOP tools (for example AspectJ) you can weave code into the super class method and avoid its execution entirely (yuck). This doesn't work if you're using proxies, you have to use bytecode modification (either load time weaving or compile time weaving). There are be mocking frameworks that support this type of trick as well, like PowerMock and PowerMockito.
I suggest you go for the refactoring, but if that is not an option you're in for some serious hacking fun.
Maybe the easiest option if inheritance makes sense is to create a new method (package private??) to call the super (lets call it superFindall), spy the real instance and then mock the superFindAll() method in the way you wanted to mock the parent class one. It's not the perfect solution in terms of coverage and visibility but it should do the job and it's easy to apply.
Even if i totally agree with iwein response (
), i admit there are some times inheritance seems just natural, and i don't feel breaking or refactor it just for the sake of a unit test.
So, my suggestion :
And then, in the unit test :
If you really don't have a choice for refactoring you can mock/stub everything in the super method call e.g.
The reason is your base class is not public-ed, then Mockito cannot intercept it due to visibility, if you change base class as public, or @Override in sub class (as public), then Mockito can mock it correctly.
Consider refactoring the code from ChildService.save() method to different method and test that new method instead of testing ChildService.save(), this way you will avoid unnecessary call to super method.
Example: