Reputation: 33
Is there any reason to have more than one verify statement when testing a specific functionality - ie. verify that multiple/ or no dependent methods were called?
For Example:
public void doSomething(int size){
if(size < 50){
return;
}
someService.someMethod();
anotherService.someMethod();
}
To test this method
@Test
public void testDoSomethingWithSmallSize() throws Exception{
testObj.doSomething(5);
verify(someServiceMock, never()).someMethod();
//IS THERE ANY VALUE TO VERFIYING MORE THAN ONE CALL?
//LIKE THIS??
verfiy(anotherServiceMock, never()).someMethod();
}
Is there value to having the second verify statement or is it unnecessary because if the first statement wasn't called the second wasn't either?
Upvotes: 0
Views: 2002
Reputation: 1508
You should verify the 2 statements because your code can change.
Unit test is some kind of documentation of your code.
If someone changes the method to call anotherService.someMethod()
inside the if
statement, your test will still pass with 1 verify and will fail with 2 verify.
Upvotes: 1
Reputation: 95614
You are right to worry that your test should only be testing one "concept" at a time, and that it is a matter of judgment about what constitutes a test that does "too much". Your original example is a good one:
@Test
public void testDoSomethingWithSmallSize() throws Exception{
testObj.doSomething(5);
verify(someServiceMock, never()).someMethod();
verify(anotherServiceMock, never()).someMethod();
// GOOD: You've called one method-under-test and
// verified two related postconditions. A perfect, small, clear test.
}
But it's easy to take this too far.
@Test
public void testDoSomethingWithAnySmallSize() throws Exception{
testObj.doSomething(1);
testObj.doSomething(3);
testObj.doSomething(5);
verify(someServiceMock, never()).someMethod();
verify(anotherServiceMock, never()).someMethod();
// LESS GOOD: You've called one method-under-test three times, but
// they share postconditions and concepts. Pragmatic, but not the
// "one test method for one test case" ideal of most frameworks.
}
@Test
public void thisShouldBeThreeTests() throws Exception{
testObj.doSomething(7);
verify(someServiceMock).doAThing(7);
verify(anotherService).doAThing(700);
testObj.doSomethingElse(9);
verify(someServiceMock).doAThing(9);
verify(anotherService).doAThing(900);
testObj.doAThirdThing(12);
verify(someServiceMock).doAThing(12);
verify(anotherService).doAThing(1200);
// BAD: Even though these are related, this could easily be three
// unrelated tests for better naming and reporting, and to help you
// identify why one case might be failing versus three. Break this up.
}
So yes, don't be afraid to have more than one verify
in the same test, but do be careful not to let your verify
statements stray to be unrelated, and be especially careful if you're resetting your test setup with Mockito's reset
method.
Upvotes: 1
Reputation: 199
YES! Part of the function of a unit test is documenting the expected behaviors of code. The test(s) should be written in a way that treats the code under test as a black box. If the code under test will do two things in a specific order (if conditions are met) then the unit test should check that all things were done under positive conditions AND that NONE of the items were done under the negative conditions.
If you only check one condition in your test, then 2 years from now, an intern might update the code, and need to remove the one task that is being checked. Your test will still pass (code removed not executed - check!) but that doesn't mean the code is behaving correctly.
Upvotes: 0