Junit 5和Mockito 3:在通过构造器注入@Mock时未引发UnnecessaryStubbingException

问题描述

查看下面的两个测试类,我从它们中假设相同的行为:抛出UnnecessaryStubbingException。但是MyTest2没有。 MockitoExtension类在认情况下应将严格性设置为严格存根。我似乎找不到有关此行为的任何书面信息,我真的很想了解它。

我更喜欢将测试写为MyTest2,因为我希望尽可能地拥有最终字段,尽管我也非常喜欢Mockito进行的严格的存根检查。。请帮助我理解两个测试之间的区别。

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);
  }
}

解决方法

我在mockito documentation中找到了原因:

仅当没有任何测试方法使用存根时,Mockito JUnit Runner才会触发UnnecessaryStubbingException。这意味着可以将默认存根放入“ setup”方法或测试类构造函数中。一种测试方法至少需要使用一次默认存根。

如果您不希望为MyTest类引发异常,则可以使用Mockito.lenientMockitoSettings。但是我想不可能为MyTest2类激活异常。