1

Looking at the two test classes below I assume the same behavior from them: to have an UnnecessaryStubbingException thrown. However MyTest2 does not. The MockitoExtension class should have strictness set to strict stubs by default. I can't seem to find any documented information about this behavior and I really want to understand it.

I prefer to write my tests as MyTest2 because I like to have final fields wherever possible, though I also really enjoy the strict stubs check done by Mockito.. Please help my understand the difference between the two tests.

package example;

import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
class MyTest {

  @Mock
  List<Integer> integerList;

  @Test
  void test() {
    Mockito.when(integerList.size()).thenReturn(10);

    System.out.println("Do something not involving list");

    Assertions.assertTrue(true);
  }
}

@ExtendWith(MockitoExtension.class)
class MyTest2 {

  final List<Integer> integerList;

  MyTest2(@Mock List<Integer> integerList) {
    this.integerList = integerList;
  }


  @Test
  void test() {
    Mockito.when(integerList.size()).thenReturn(10);

    System.out.println("Do something not involving list");

    Assertions.assertTrue(true);
  }
}
Niklas Larsson
  • 99
  • 1
  • 11
  • At the point at which the unit ParameterResolver creates the mock, the UniversalTestListener hasn't yet been created (that happens in DefaultMockitoSession()), and so mockito doesn't know about that mock. Seems like a bug. – tgdavies Oct 02 '20 at 13:21
  • Hmm, that's good info. Maybe I should try and contact the developers for Mockito then. – Niklas Larsson Oct 05 '20 at 05:36

1 Answers1

2

I found the reason in the mockito documentation:

Mockito JUnit Runner triggers UnnecessaryStubbingException only when none of the test methods use the stubbings. This means that it is ok to put default stubbing in a 'setup' method or in test class constructor. That default stubbing needs to be used at least once by one of the test methods.

If you do not want the exception to be thrown for the MyTest class, you can use Mockito.lenient or MockitoSettings. But I guess it is not possible to activate the exception for the MyTest2 class.

flaxel
  • 4,173
  • 4
  • 17
  • 30
  • I don't setup any stubbing in the outside of the test though. So I don't really agree this being the reason for the exception not being thrown. :( – Niklas Larsson Oct 05 '20 at 05:35