Rosie
Rosie

Reputation: 33

Is there value in having more than one verify statement in unit tests?

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

Answers (3)

Matthieu Saleta
Matthieu Saleta

Reputation: 1508

You should verify the 2 statements because your code can change.

Unit test is some kind of documentation of your code.

  • Verifying both statements means that both statements MUST not be called.
  • Verifying only one means that only the 1st statement MUST not be called.

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

Jeff Bowman
Jeff Bowman

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

Charles Hasegawa
Charles Hasegawa

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

Related Questions