Thanks for the extra details @Mohan_Radhakrishnan, that is super helpful. I also put two and two together and realised this is (in part) a continuation of: How do I pass Eio 'env'?.
In light of that I think the question becomes a lot clearer. And yes, if your point of abstraction is an _ Eio.Path.t
then at the moment eio.mock
does not offer ways to mock the required interfaces (directories and files). This actually gets very complicated very quickly as you end up needing to mock Eio.Fs.Pi.DIR
and Eio.File.Pi.RO/RW
. The logic between all of your mocks will need to take into account file creation, handlers for calls to stat
etc. If you are curious to head down this route, I started mocking Fs.Dir
and File.Ro
, and I think opening an issue on Eio would be the correct next step. Here is what that might then look like:
module type WalWriter = sig
type t
val v : _ Eio.Path.t -> t
val write : t -> Cstruct.t -> unit
val read : t -> string
end
let make_stat ~size kind : Eio.File.Stat.t = {
dev = 0L;
ino = 0L;
kind;
perm = 0;
nlink = 0L;
uid = 0L;
gid = 0L;
rdev = 0L;
size = Optint.Int63.of_int size;
atime = 0.;
mtime = 0.;
ctime = 0.;
}
let test1 wal =
assert (String.length (WalWriter.read wal) = 4)
let test () =
let mock_reader = Mock.File.make_ro "wal-reader" in
Mock.File.on_read mock_reader [ `Return "1234" ];
let t = Mock.Fs.make "mock-wal" in
let path : _ Eio.Path.t = ((t :> Eio.Fs.dir_ty r), "/mock.log") in
Mock.Fs.on_open_in t [ `Return mock_reader ];
(* For your stat to check if the file exists, not strictly necessary *)
Mock.Fs.on_stat t [ `Return (make_stat ~size:4 `Regular_file) ];
(* For the file loading stat *)
Mock.File.on_stat mock_reader [ `Return (make_stat ~size:4 `Regular_file) ];
let wal = WalWriter.v path in
test1 wal
let () =
Eio_mock.Backend.run @@ fun () ->
test ()
Pretty gnarly… I think you would be better off using the filesystem directly in your tests instead of trying to mock it. Note as well that I changed your module signature a little to be more conventional. I hope this helps.