在集成测试中模拟是否被认为是一种好的做法



有人告诉我@Mock通常只用于单元测试,但我认为它对于替换测试类之外的外部部分很有用。在集成测试中进行mock是否正确?

最后,这一切都是关于措辞的。

当你从最基本的意义上思考"正确"时,就像正确一样,答案很简单:不。

您可以看到,集成测试的目标是确保您的综合系统(由多个不同组件组成)按预期运行。集成测试的目的是验证组件的"管道"是否按预期工作。因此:当系统的部分被模拟出来时,您无法验证您的系统是否工作。

但是,你可以不那么严格地认为"正确"。

例如:销售汽车的公司必须测试ECU。基本上是一块硬件,运行着一个潜在的巨大软件堆栈。这些ECU通常在车厢内运行。所以当你想集成测试电子控制单元时,你必须把电子控制单元放进车里进行测试,对吧?一辆可能还不存在的汽车。这里的解决方案是:有硬件模拟器。你把电子控制单元插入模拟器,电子控制单元就会"思考"一辆真正的汽车。

所以:有很好的理由声称"一个真正的集成测试不能使用mocking",但与此同时,在现实世界中,这种"mocking"总是发生。

因此,真正的答案是:这取决于背景。因此,没有一个普遍的答案。相反,这是关于通信。你"只需"确保你的团队/组织中的所有人对这些术语都有相同的理解。

这个词本身可以有不同的解释。你(共同!)选择最适合你需求的定义,然后确保所有为你的项目做出贡献的人都分享这个观点(或者至少知道它)。

是的,在某些情况下,您可以在集成测试中使用@Mock(主要用于存根)。特别是如果你想集成测试你的类的一部分。

例如,如果你想测试与外部服务A的通信,那么嘲笑与服务B的通信有关的其余部分没有错。

另一个例子是,如果您测试一个工作流,那么通过模拟单个步骤/活动来测试路径的集成测试是有意义的。

个人观点(有争议,有很多不同的术语):单元和集成测试有很多阴影。在我的理解中,单元测试只是孤立地测试单个类。但我经常编写测试几个类组合的测试,在我看来,这已经是一种集成测试了。还有一些测试可以通过模拟外部服务来测试单个组件,我称之为系统测试。然后可能会有测试针对未被嘲笑的外部服务测试单个组件,我将这些测试称为系统集成测试。在所有这些场景中,模拟/截断某些部分并专注于单个测试类中的一个方面可能是可行的。

在集成测试中进行mock正确吗?

一般情况:在集成测试中不模拟

一般来说,嘲讽测试和集成测试不适合放在一起
大多数时候,你想使用一个或第二个,而不是两者都用。

但有时您想要在集成测试中进行模拟,因为您想要断言的逻辑只能在这个框架中正确测试

如果您依赖于一个为您执行许多任务的框架或库,并且您需要测试在此框架中指定的逻辑,那么您将通过编写比单元测试更多的集成测试来完成,因为单元测试通常根本不足以覆盖应用程序代码
但完全集成测试与其他组件完全没有隔离(因此可能会产生副作用:测试可能会因为糟糕的原因而成功),这些测试通常很慢,因此通常不会在为开发人员提供后期反馈的本地机器上执行
因此,只编写完全集成测试通常是不可接受的。对于这种上下文,在集成测试期间模拟的想法非常有意义。

Spring Boot和测试切片:一个很好的例子

由Spring Boot启动的应用程序属于这一类
事实上,我们希望运行容器来测试一些特定的部分(持久性、控制器等),但我们不想加载整个容器和相关组件
所以嘲笑某些特定的部分真的很有意义
Spring Boot的测试切片允许在测试中的组件以某种集成级别进行测试时进行模拟:

Spring Boot的自动配置系统适用于应用程序但有时对测试来说可能有点太多了。这通常有助于只加载配置中测试应用程序的"切片"。例如,您可能想要测试Spring MVC控制器正在正确映射URL,而您不希望在这些测试中涉及数据库调用,或者您可能想要测试JPA实体,而您对web层不感兴趣时测试运行

有两种类型的测试。单元测试和集成测试。您可以使用Mocks来执行单元测试。在单元测试中,您测试各个方法,重点是测试各个方法的行为。因此,在单元测试中使用mock是有意义的。

因为您不能使用mock来执行集成测试。集成测试通常涉及集成的所有依赖系统,我们在任何服务器/云上执行它。

最新更新