不要再使用了mock了
乙醇 创建于 9 months 之前
最后更新: 9 months 之前
阅读数: 602
最近看到一篇关于mock的文章,觉得挺有道理的,,简单总结分享一下,原文在这里:https://levelup.gitconnected.com/why-mocks-are-considered-harmful-b4e8fe60478d。 文章的观点很简单,就是mock其实是弊大于利的。
自动化测试涉及到很多技术,其中mock技术我们应该尽量避免使用。mock用的好其实也只是锦上添花,用的不好的话则会给你带来一些过度的自信。
首先看下什么是mock。mock其实就是模拟代码中的一些外部访问行为,比如访问第三方的付款api或者是对数据库进行访问,这会给单元测试带来一些好处
- 运行加速,因为你不需要访问额外的服务;
- 提升稳定性,第三方服务提供商的一些不稳定因素被规避掉了
不过mock是为一些具有副作用的代码服务的,也就是说这些代码其实是依赖于外部服务,并不是依赖于各种参数的输入。我们可以把函数分成两类
- 纯粹的函数:没有外部依赖的函数
- 不纯粹的函数:有外部依赖的函数
mock带来的问题
mock不等同于其替换掉的服务。
比如你把代码中数据库访问的部分给mock掉了,这意味着你的代码可能会在有mock的时候工作良好,然而你还是需要进行集成测试以确保在没有mock的时候也可以正常工作。
不可能进行特性平替
如果你使用的是简单的mock方式,那么mock可能不会返回一些有用的数据,你花在mock上的时间越多,mock返回的data可能会约实用。然而mock不能平替被mock系统的方方面面。
开发了mock但不使用其实就是浪费时间
如果你开发了数据库的mock但从不使用的话,这就是浪费时间了。在现实世界中这是很有可能发生的,因为代码可能需要获取一些真实配置去做初始化,而mock的时候却很难满足这一条件。
如何去找到mock的替代方案
很简单,就是重构代码,把代码重构成纯粹的函数和不纯粹的函数两种,纯粹的函数是不需要mock就可以测试的,,不纯粹的函数则可以通过集成测试来进行验证。
举个例子
def logic():
x = addition(1, 3)
y = multiplication(2, 4)
z = x + y
database_write(z)
return
上面的函数就是不纯粹的函数,因为其访问了db,然而我们还是可以把这个函数重构成1个纯粹函数和另一个不纯粹的函数
def calc(a, b, c, d):
x = addition(a,b)
y = multiplication(c,d)
return x + y
def logic():
z = calc(1, 5, 2, 4)
database_write(z)
return
这样calc函数可以用单元测试覆盖了,而logic则留给集成测试去考虑吧。
最后尽可能的优化你的自动测试方案,让更多的代码都通过自动化进行覆盖。
总结
mock短期来看可能是一种解决问题的方式,然而长期看来确是一个麻烦的问题。如果你想快速交付软件产品的话,那么你应该少花时间在mock上,多花点时间在重构和自动化测试上面。