问题 如果我的测试中有验证,期望是多余的吗?


我对期望和验证的目的和差异感到困惑。例如。

@Tested FooServiceImpl fooService;
@Injectable FooDao fooDao;

@Test
public void callsFooDaoDelete() throws Exception {
    new Expectations() {{
        fooDao.delete(withEqual(1L)); times = 1;
    }};

    fooService.delete(1L);

    new Verifications() {{
        Long id;
        fooDao.delete(id = withCapture()); times = 1;
        Assert.assertEquals(1L, id);
    }};
}

首先,如果这个测试编写得不好,请告诉我。

第二,我的问题:期望部分对我来说似乎是多余的,我无法想出一个不会出现的例子。


11978
2018-05-14 00:42


起源

我已经更改了标题,以便更好地反映您在页面底部的问题。如果我误解了这个问题,请随时回复我的更改。 - Thunderforge
老线程,我知道,但我的理解是松散而简洁的:An Expectations 块处理的东西 可能 发生;一个 Verifications 块处理的东西 一定有 发生了。 - Laird Nelson


答案:


的目的 Expectations 是允许测试 记录预期结果 对于模拟方法和/或构造函数,根据测试代码的需要。

的目的 Verifications 是允许测试 验证预期的调用 模拟方法和/或构造函数,由被测代码制作。

因此,通常情况下,测试不会同时记录  验证相同的期望(其中“期望”指定对运行的测试代码时预期发生的模拟方法/构造函数的一组调用)。

考虑到这一点,示例测试将如下所示:

@Tested FooServiceImpl fooService;
@Injectable FooDao fooDao;

@Test
public void callsFooDaoDelete() throws Exception {
    fooService.delete(1L);

    new Verifications() {{ fooDao.delete(1L); }};
}

13
2018-05-14 14:55



我还是不明白这一点。在您的示例中,您可以使用Expectations块实现相同的效果,对吧?什么时候需要验证块? - T3rm1
当你想根据时间编写测试时,你需要一个验证块 “安排行为断言” 要么 “当时的时候” 样式。 - Rogério
@Rogério我理解这个答案,但为什么你能在预期的阻止中设置验证呢?例如: times, minTimes 等什么情况会想要在期望区块中使用这些验证? - PDStat
由于我在第三段中描述的原因,即避免在测试中编写重复的代码。如果测试需要记录给定的期望,并且它也恰好想要检查固定数量的匹配调用,那么拥有一个允许干净,简短的测试而没有无意义重复的API更有意义。 - Rogério
基本上,如果你想避免锅炉板代码和简单 times类似的验证对您来说已经足够了,您可以将其置于期望块中,以使测试更容易开发和阅读。这可能会让您感到困惑,因为您在技术上验证了预期阻止,但就个人而言,我可以接受这一点,因为我看到了简单的好处。 - wst