Issue
When writing test cases the usual pattern is setup
> execute
> verify
. This results in unit tests that look like this:
@Test
void testSomething() {
// Setup
when(someMock.someMethod()).thenReturn("someValue");
// Execute (the doSomething implementation would invoke someMock.someMethod)
testee.doSomething();
// Verify
verify(someMock, times(1)).someMethod();
}
My question is, is it necessary to include the verify
call considering the when call
will raise a UnnecessaryStubbingException
exception?
This question only applies in cases where times
is 1
since the absence of UnnecessaryStubbingException
only implies that someMethod
has been called once and with the correct arguments and there may be cases where you want to verify that someMethod
has been called never
. Without the verify the test would look like this and achieve the same checks:
@Test
void testSomething() {
// Setup
when(someMock.someMethod()).thenReturn("someValue");
// Execute (the doSomething implementation would invoke someMock.someMethod)
testee.doSomething();
}
Edit: A friend pointed out that verifyNoMoreInteractions
relies on you having verify
calls so I guess this is important to consider.
Edit 2: I've changed "necessary" to "preferred" in the title since I'm more interested in the pros/cons of each approach versus what is technically required.
Thanks in advance!
Solution
It is not necessary, as you mentioned - technically test validates this behavior. So the choice should go from preferences and expertise of your team. I personally think having explicit verification step makes your test more readable and maintainable. Few reasons:
- You can have more
when
invocations, not relevant to verification logic, this will "hide" the test intention, e.g.
@Test
void testSomething() {
// Setup
when(someMock.someMethod()).thenReturn("someValue");
when(someMock2.someMethod2()).thenReturn("someValue2");
when(someMock3.someMethod3()).thenReturn("someValue3");
// Execute (the doSomething implementation
// would invoke someMock.someMethod)
testee.doSomething();
// code reviewer - "hm? what do we really test here?"
}
- From API perspective throwing of exception in
UnnecessaryStubbingException
inwhen
is not obvious - this can bring a confusion for occasional code reader who missed that fact. Havingverify
makes the intention of test clear for almost any developer, even coming from other tech stack - Some developers can come from earlier Mockito versions where throwing of
UnnecessaryStubbingException
was not the case UnnecessaryStubbingException
is only raised when Mockito is in strict mode. If this setting is changed to lenient down the line you'd no longer be able to rely on this exception being raised.- You can create scenarios where not including
verify
calls means subsequentverifyNoMoreInteractions
calls will fail.
Answered By - udalmik
Answer Checked By - Candace Johnson (JavaFixing Volunteer)