【问题标题】:Mockito throws UnnecessaryStubbingException for stub defined in generic @BeforeEach setup methodMockito 为通用 @BeforeEach 设置方法中定义的存根抛出 UnnecessaryStubbingException
【发布时间】:2021-05-21 20:27:40
【问题描述】:

我有一个单元测试类,我的测试单元依赖于另一个类。使用 Mockito 模拟依赖项,然后使用 JUnit 的 @BeforeEach 注释设置在每个单元测试之前运行的通用存根。见下面的伪代码。

@ExtendWith(MockitoExtension.class)
public class FooFactoryTest {

    @Mock
    private BarDependency barDependency;

    @InjectMocks
    private FooFactory unitUnderTest;

    @BeforeEach
    public void setup() {
        when(barDependency.leftBar(any())).thenReturn(new Bar());
        when(barDependency.rightBar(any())).thenReturn(new Bar());
    }

   ... many tests ...

此设置非常适合我的 10 个单元测试中的 9 个。不幸的是,我的一项测试因以下错误而失败:

org.mockito.exceptions.misusing.UnnecessaryStubbingException: 
Unnecessary stubbings detected.
Clean & maintainable test code requires zero unnecessary code.
Following stubbings are unnecessary (click to navigate to relevant line of code):
  1. -> at nl.devillers.mockito.FooFactoryTest.setup(FooFactoryTest.java:69)
Please remove unnecessary stubbings or use 'lenient' strictness. More info: javadoc for UnnecessaryStubbingException class.

现在,我了解了错误及其引发的原因,因为在该特定测试中,我的待测单元很早就短路了,并且没有击中所有已设置的存根。我知道 Mockito 中有一个 lenient 选项,但这会禁用对整个类/项目的检查。

我的问题是:如何为一个特定的单元测试禁用这种严格性?

再次重申:我确实想在班级或项目级别禁用严格性,因为我认为这是有价值的检查。我也确实想将我的设置代码移动到需要存根的测试,因为那样我必须复制设置代码九次。在这种情况下,我只想禁用或跳过此特定测试的检查。

【问题讨论】:

    标签: java unit-testing junit mockito junit-jupiter


    【解决方案1】:

    您可以通过使用未调用的存根重置模拟来避免在测试级别进行此检查。这是一种变通方法,但它可以让您通过测试,而不必使模拟对整个测试类宽松或完全从您的设置方法中删除模拟。

    要重置您的 barDependency 模拟,请将以下代码行添加到 结束您失败的测试并带有 UnnecessaryStubbingException

    Mockito.reset(barDependency);
    

    如果barDependency 上的没有个存根被使用,您也可以将此行放在测试的开头并使用其他安排,这样会更简洁一些。或者,将它放在测试方法的顶部,然后设置您确实需要的存根。这实质上会覆盖通用设置方法中正在设置的任何内容。

    【讨论】:

      【解决方案2】:

      您也可以在@BeforeEach 的代码中使用 lenient,如下所示:

      @BeforeEach
      public void setup() {
          lenient().when(barDependency.leftBar(any())).thenReturn(new Bar());
          lenient().when(barDependency.rightBar(any())).thenReturn(new Bar());
      }
      

      这应该不是必需的,根据UnnecessaryStubbingException 中的此文档:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-28
        • 1970-01-01
        • 2016-01-12
        • 1970-01-01
        • 2020-04-27
        相关资源
        最近更新 更多