How usual is to have a test double in OCaml that would fake a database connection ?
Lets say you want to test a small API on top of a database and the way this works is by providing a Connection
type to each function that API exposes.
Something like:
let get_data connection = do_something_with_connection
How would this be unit tested ?
On a larger note is is this kind of testing usual in OCaml, given the fact that OCaml's powerful type system already makes sure that you don't make weird mistakes ?
You would create an object which has all of the same method names as Connection each with the same signatures (and with stub functionality, obviously). Then you can instantiate one of these objects and declare it as being a Connection via subtyping. Then it can be passed into any of the functions.
Here is a helpful bit about subtyping (which, it should be noted, is not the same things as inheritance in Ocaml).
Build your module with a functor, which takes the Connection module as its argument. Then you can stub out the Connection module in your tests.
So, for example, your db.ml file could look kind of like this:
(* 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
Then in your test_db.ml you can just stub out the Connection module
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"])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With