我们有相当多的ocaml代码,模块之间存在许多紧密耦合的依赖关系。最近,我们开始采用functor方法来解耦这些模块。因此,如果模块A依赖于模块B和C,我们会在声明中按照以下方式进行:
module A: (B:B_Signature) (C:C_Signature) = struct ... end
像这样,我们可以在模块A中注入一个“虚拟的”B或C模块来回答这些签名,进行单元测试,并且仍然可以创建具有真实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和0供函数g使用。
这些默认值,空字符串和零,只是一个示例。我知道最终我会希望这更加可配置,我想创建模拟并指定某些函数的返回值,甚至能够检查调用模拟函数时使用的参数等等,但目前为止,对于这种简单情况,我正在寻找一种不必手动输入和实现所有内容的解决方案。
我没有找到任何可以在OCaml中完成这个任务的框架。
我试图通过camlp4和代码生成来弄清楚如何做到这一点,但文档好像有点有限,我真的没有看到是否可能。
所以我的问题是,是否有人知道一个框架或者是否有一种代码生成的方法可以从OCaml签名中创建这种样板模块?
Kasper