First, when you unit-test, test all public methods. In your example m1
and m2
are public, so you'd have tests for both.
There are several reasons that you might want to stub or mock m2
:
If, when you test
m1
, you encounter any problems becausem1
callsm2
, stub or mockm2
. Some problems you might encounter:m2
might call external servicesm2
might just be slow- it might be difficult to call
m1
with parameters that satisfym2
(yourm2
has no parameters, but I'm speaking generally)
Sometimes, when you test a method that calls another method and also test the other method, you find that there is duplication between the tests of the two methods -- some of the tests of the calling method are really testing the called method. Deal with that by stubbing or mocking the called method out of the calling method, testing the calling method just enough to prove that the called method is called, and thoroughly testing the called method.
If you do TDD, you might write
m1
before you writem2
. You would then stub or mockm2
so that your tests ofm1
would pass, and then go on to test and writem2
.
But if you don't have any reason to stub or mock m2
, don't. It is common and reasonable for a method to call other methods in ways that don't require stubbing or mocking. The called methods might be short and simple, or the calling method might just be broken up into a bunch of subsidiary methods for readability. That's even true if the called method is in another class (because it's used by more than one calling method); if it is fully tested by tests of methods that call it, and if there is no duplication between tests, there is no need to stub or mock.
The example above of mocking m2
without running m1
is a perfectly normal thing to want to do and it gets the job done, but it's ugly since Mockito takes over all of a class's methods. You can do it more nicely with a Mockito spy, discussed here: What is the difference between mocking and spying when using Mockito?.
A a = spy(new A());
doNothing().when(spy).m2();
a.m1();
# check state of a