问题 函数编程和模拟对象


我最近正在观看有关Clojure的网络直播。在演讲者中,主持人在讨论Clojure的FP性质的背景下发表了评论,其中包括(我希望我不会歪曲他)“Mock对象嘲笑你”。

当我在微软的Reactive Framework开始出现时观看网络直播时,我也听到了类似的评论。它类似于“模拟对象适合那些不懂数学的人”

现在我知道这两个评论都是笑话/诙谐等等(并且可能被严重释义),但是它们的基础显然是一些我不理解的概念,因为我还没有真正转向FP范式。

所以,如果有人能够解释FP是否确实使嘲弄变得多余,我将不胜感激,如果有的话。


9166
2017-08-25 10:32


起源

在FP中,对象模拟你! /米姆


答案:


在纯FP中,您具有引用透明函数,每次使用相同输入调用它们时都会计算相同的输出。因此,您需要的所有状态必须作为参数显式传入,而作为函数结果传递出去,没有任何有状态的对象以某种方式“隐藏”在您调用的函数之后。但是,这是您的模拟对象通常所做的事情:模拟您测试的主体所依赖的一些外部隐藏状态或行为。

换一种说法: OO:您的对象结合了相关的状态和行为。 纯FP:状态是你在函数之间传递的东西,它们本身是无状态的,只依赖于其他无状态函数。


8
2017-08-25 12:26



好。谢谢。但是大概是在函数之间传递的状态可能是模拟对象或“真实对象”,因此模拟对象仍然适合测试FP解决方案 - 不是吗? - Simon Woods
在纯FP中,OO意义上没有对象。有数据结构,可以是用户定义的。在某些语言中有接口的远亲:Haskell有类型类,它们基本上是一组必须为该类型类中的每种数据类型定义的函数。所以是的,你可以编写你的函数来操作某个类型类的数据类型,并在另一种数据类型上测试它,而不是你在生产中使用的数据类型。在F#或Scala中,您可以实际操作功能样式的.NET或Java对象,甚至可能需要使用实际的模拟对象。 - Christoph


我认为重要的是要考虑使用测试的想法可以帮助您构建代码。模拟真的是推迟你现在不想采取的决定(以及一种被广泛误解的技术)。而不是对象状态,考虑部分函数。您可以编写一个函数,将其行为的一部分推迟到传入的部分函数中。在单元测试中,这可能是一个虚假的实现,让您只关注手头的代码。稍后,您将使用实际实现来构建新代码以构建系统。

实际上,当我们开发Mocks的想法时,我总是这样想着Mocks。对象部分是偶然的。


8
2018-01-30 13:20