在集成测试中模拟是否被认为是一种好习惯?

时间:2018-08-31 02:02:53

标签: java spring mocking mockito

有人告诉我,@ Mock通常仅用于单元测试,但我认为对于代替测试类之外的外部部件很有用。在集成测试中模拟是否正确?

4 个答案:

答案 0 :(得分:4)

最后,这全都与措辞有关。

当您从“ correctness”的最根本意义上考虑“正确”时,答案很简单:不。

您看到,集成测试的目标是确保您的集成系统(由多个不同组件组成)能够按预期运行。集成测试的目的是验证组件的“连接”是否按预期进行。因此:当模拟出系统的 parts 时,您无法验证系统是否正常工作。

但是,您可以不太严格地认为“正确性”。

示例:销售汽车的公司必须测试ECUs。基本上是一块硬件,运行着可能庞大的软件堆栈。这些ECU通常在汽车中运行。因此,当您要对ECU进行集成测试时,是否必须将ECU放入汽车中进行测试?可能还不存在的汽车。这里的解决方案:有硬件仿真器。您将ECU插入该仿真器中,然后ECU就“思考”在真实汽车内。

因此:有很好的论据声称“真正的集成测试不能使用模拟”,但同时,在现实世界中,这种“模拟”一直在发生。

因此,真正的答案是:它取决于上下文。因此,没有一个普遍的答案。而是关于通信。您“仅”必须确保您的组/组织中的所有人对这些术语具有相同的理解。

该术语本身可以用不同的方式解释。您(共同!)选择最适合您需求的定义,然后确保为您的项目做出贡献的所有人都共享该观点(或至少知道这一点)。

答案 1 :(得分:3)

  

在集成测试中模拟是否正确?

一般情况:您不会在集成测试中嘲笑

一般而言,模拟测试和集成测试不太适合。
大多数时候,您想使用一个或两个,而不是两者都使用。

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

如果您依赖于为您执行许多事情的框架或库,并且您需要测试在此框架中指定的逻辑,那么与单元测试相比,编写更多的集成测试会结束,因为单元测试通常是不够的完全涵盖了应用程序代码。
但是完全集成测试与其他组件完全没有隔离(因此可能会产生副作用:测试可能会因不良原因而获得成功),这些测试通常很慢,因此通常不会在本地计算机上执行,从而无法为开发人员提供后期反馈。
因此,仅编写完全集成测试通常是不可接受的。 对于这种情况,在集成测试中模拟的想法是很有意义的。

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

由Spring Boot启动的应用程序属于此类别。
实际上,我们希望运行容器以能够测试某些特定的部分(持久性,控制器等),但我们不想加载整个容器和相关组件。
所以嘲笑一些特定的部分是很有意义的。
Spring Boot的Test slices允许在某种程度的集成度下测试被测组件时进行模拟:

  

Spring Boot的自动配置系统非常适合应用程序   但有时对于测试来说可能有点过多。它通常有助于   仅加载测试a所需的配置部分   应用程序的“切片”。例如,您可能要测试   Spring MVC控制器正确映射了URL,并且您不希望   在这些测试中涉及数据库调用,或者您可能想测试   JPA实体,您对Web层不感兴趣   测试运行

答案 2 :(得分:2)

是的,在某些情况下,您可以在集成测试中使用@Mock(主要用于存根)。尤其是如果您要集成测试班级的一部分。

例如,如果您要测试与外部服务A的通信,则嘲笑与服务B的通信的其余部分没有错。

另一个示例,如果您测试工作流程,则有一个集成测试可以通过模拟单个步骤/活动来测试路径。

个人意见(有争议,并且有许多不同的术语):单元测试和集成测试有很多阴影。以我的理解,单元测试只是隔离地测试单个类。但是我经常写测试来测试多个类的组合,在我看来,这已经是一种集成测试。然后有一些测试可以通过模拟外部服务来测试单个组件,我称它们为“ 系统测试”。然后可能会有针对未模拟的外部服务测试单个组件的测试,我称这些测试为“系统集成测试”。在所有这些情况下,模拟/存根某些部分并在单个测试类中专注于一个方面都是可行的。

答案 3 :(得分:0)

有2种测试类型。单元测试和集成测试。 您可以使用Mocks进行单元测试。在单元测试中,您测试单个方法,并且重点在于测试单个方法的行为。因此,在单元测试的情况下,使用模拟是有意义的。

无法使用模拟执行集成测试的地方。集成测试通常涉及集成的所有相关系统,我们在任何服务器/云上执行它。

相关问题