据我所知,lenient
会使StrictStubbing引发的异常静音。基于此,不应该使用lenient
,可能在进行TDD时只是暂时的,因为严格的存根异常通常意味着您的代码要么是错误的,要么是设计糟糕的测试,要么是添加了不必要的行。
是否存在实际需要lenient
或对测试有用的场景?
关于何时使用lenient
的一个很好的例子是在@BeforeEach
块中。
如果您在几乎所有的测试用例中都使用存根,那么在before-each中创建存根是有意义的。如果有任何测试不使用存根,则需要使用lenient
来防止严格的存根引发错误。这是mockito文档中使用的示例:
@Before public void before() { when(foo.foo()).thenReturn("ok"); // it is better to configure the stubbing to be lenient: // lenient().when(foo.foo()).thenReturn("ok"); // or the entire mock to be lenient: // foo = mock(Foo.class, withSettings().lenient()); } @Test public void test1() { foo.foo(); } @Test public void test2() { foo.foo(); } @Test public void test3() { bar.bar(); }
例如,如果您需要在短时间内完成从Mockito 1到Mockito 2的迁移(后者引入了严格的存根(,它非常有用。
引入严格的存根来检测不必要的存根并编写更干净的测试。如果您遇到异常,则应将重点放在改进测试用例上,而不是绕过严格的存根检查。
我刚刚发现了一个不寻常的有效用途。我们对代码进行了更改,默认情况下禁用了一个功能(在将来的版本中完全删除它之前(。我们需要一个测试来验证禁用是否有效,所以我们需要将一些标志模拟为false。然而,我们还需要模拟其他一些值,因为如果禁用该功能的代码(测试该标志(以某种方式被破坏,该功能的默认设置将导致它什么都不做,因此我们将无法观察到标志的失败。
总结一下:在成功的案例中,我们会通过嘲讽得到UnnecessaryTubbingException,但如果没有它,失败的案例就不会真正失败。因此,我们将这些具体的嘲讽标记为宽容。
宽大处理((在编写参数化测试时也很有用。参数化测试可以比严格的存根更有效地减少冗余代码。因此,如果您正在使用参数化测试(例如,测试所有异常条件(,如果某些调用需要存根,而其他调用则不需要存根,则可能需要宽大处理((存根。不过,首先要让你的存根尽可能具体。