在OCaml中使用一个会伪造数据库连接的测试加倍是多么常见?
假设您希望在数据库之上测试一个小型API,其工作方式是为API公开的每个函数提供Connection
类型。
类似的东西:
let get_data connection = do_something_with_connection
如何进行单元测试?
更大的一点是OCaml中常见的这种测试,因为OCaml强大的类型系统已经确保你不会犯奇怪的错误吗?
答案 0 :(得分:3)
您将创建一个对象,该对象具有与Connection相同的所有方法名称,每个具有相同的签名(显然具有存根功能)。然后,您可以实例化其中一个对象,并通过子类型将其声明为Connection。然后它可以传递给任何函数。
Here对于子类型是有用的(应该注意,它与Ocaml中的继承不同)。
答案 1 :(得分:1)
使用仿函数构建模块,该仿函数将Connection模块作为其参数。然后,您可以在测试中存根连接模块。
因此,例如,您的db.ml文件可能看起来像这样:
(* The interface of Connection that we use *)
module type CONNECTION = sig
type t
val execute : string -> t -> string list
end
(* functor to build Db modules, given a Connection module *)
module Make(Connection : CONNECTION) = struct
...
let get_data connection =
do_something_with (Connection.execute "some query" connection)
...
end
然后在test_db.ml中,您可以删除连接模块
let test_get_data () =
let module TestConnection = struct
type t = unit
let execute _ _ = ["data"]
end in
let module TestDb = Db.Make(TestConnection) in
assert (TestDb.get_data () = ["munged data"])