Reputation: 1507
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!
Upvotes: 0
Views: 1034
Reputation: 7988
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:
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?"
}
UnnecessaryStubbingException
in when
is not obvious - this can bring a confusion for occasional code reader who missed that fact. Having verify
makes the intention of test clear for almost any developer, even coming from other tech stackUnnecessaryStubbingException
was not the caseUnnecessaryStubbingException
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.verify
calls means subsequent verifyNoMoreInteractions
calls will fail.Upvotes: 2
Reputation: 1270
No, It is not necessary to add Verify for each when call in Mockito. Every testcase should be deterministic in nature.
To answer your question the preferred way is to use in this particular case is to verifyNoMoreInteractions
or verify(somemock, never()).someMethod()
It is not necessary that you always need verify. You can use assertions as well. But, A testcase must have either of them.
For Eg. If you are sure that some method is going to throw an Exception.
@Test(expected = HeyIAmException.class)
void testSomething() {
classUnderTest.someMethodWhichThrowsException();
}
or In Junit 5.
@Test
void testSomething() {
when(someMock.someMethod()).thenReturn("someValue");
HeyIAmException exception = assertThrows(HeyIAmException.class, () ->
classUnderTest.someMethodWhichThrowsException()
);
assertEquals(exception.getCode(),rightCode);
}
In your approach addition to Udalmik's answer I have following more lines to add.
someMethod
could throw the exception.Upvotes: 0
Reputation: 11
If you're already aware that your piece of code will throw an exception, its better to have a test case covering it like below
@Test(expected = UnnecessaryStubbingException.class)
A test case(the one you have shown skipping verify) without any assertion or verify statement has no meaning in it. It's a good approach to have verify check for cases when methods have void return type.
Upvotes: 0