2013-12-18 243 views
5

我们有相当多的ocaml代码,模块之间有很多硬耦合的依赖关系。最近,我们一直移动到仿函数的方法来分离这些模块,所以如果我们依赖于模块B和C模块A,我们走这样的声明:OCaml模拟模块生成

module A: (B:B_Signature) (C:C_Signature) = struct ... end 

这样我们就可以注入一个'模拟'B或C模块,回答这些签名,在模块A中进行单元测试,并且仍然可以创建带有真实B和C模块的生产模块。现在的问题是,我们现在必须手动输入这些模拟模块,这有点阻碍了,因为它通常是装载样板。

所以,我正在寻找一种方法来从ocaml模块生成'模拟'模块,而不是手工输入它们。我的意思跟那就是如果我有几个功能模块,具有以下特征

module type A = 
    sig 
    val f: string -> int -> string 
    val g: string -> string -> int 
    end 

我想产生一个模拟实现,例如像这样

module A_mock = 
struct 
let f _s _i = 
    "" 
let g _s1 _s2 = 
    0 
end 

所以,这是一个具有相同签名的函数的模块,但具有f和g的实现,忽略它们的参数并默认返回,函数f的空字符串和函数g的0。

那些默认值,空字符串和零,只是一个例子。我知道我最终会希望这个更具可配置性,我想创建模拟并指定某些函数的返回值,甚至可以检查调用函数被调用的参数等等,但现在,对于这个简单的例子,我正在寻找一种解决方案,而不是手工输入和实现这一点。

我没有找到任何框架为OCaml做到这一点。

我想知道如何通过camlp4和代码生成,但文档似乎是有限的,我真的不知道它是否可能。

所以,我的问题,是否有人知道一个框架,或者是否有代码生成方式来创建这种从OCaml中签名的样板模块?

卡斯帕

+0

Kapput(http://kaputt.x9c.fr/)具有'Mock'模块。但我怀疑这是你想要的。是不是你想要更像一个间谍?在这种情况下,我认为'ppx'或'camlp4'应该可以解决这个问题,尽管目前学习曲线很陡。 – nlucaroni

+0

是的,的确,在这种简单的情况下,它更像是间谍,你是对的。但最后我想要更多的“Mockito风格”,引用Java对应,可能性(也就是告诉函数在哪种情况下必须返回什么参数,等等,这更多的是我认为的模拟)。但是,事实上,camlp4的文档实际上并不是很好(或者我还没有找到好的文档),所以如果有人能够将我设置在这个简单的间谍模块的正确路径上,那就太好了。 – Kasper

+0

我最近把工作转移到了他们使用Mockito的地方,所以我正在熟悉整个Mock和Spy的概念,所以很高兴能够重新确认我知道我在说什么;)。在过去的几个星期里,我其实一直在思考这个问题,我一直在这个问题上讨论,因为根据camlp4和ppx可能会浪费时间。 – nlucaroni

回答

0

好吧,我创建了一个的Camp4库,将创建一个模拟模块的开始。在github上有一个wiki页面,有一些解释,还有一个示例签名文件和两个脚本,现在也在master分支中签入。希望能够扩展这一点并使其更加强大,当我们开始更多地使用它时,我们也可能会得到关于它的想法。

https://github.com/KasperJanssens/mockaml