在OCaml中进行双重测试

时间:2011-08-19 18:29:18

标签: unit-testing ocaml

在OCaml中使用一个会伪造数据库连接的测试加倍是多么常见?

假设您希望在数据库之上测试一个小型API,其工作方式是为API公开的每个函数提供Connection类型。

类似的东西:

let get_data connection = do_something_with_connection

如何进行单元测试?

更大的一点是OCaml中常见的这种测试,因为OCaml强大的类型系统已经确保你不会犯奇怪的错误吗?

2 个答案:

答案 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"])