I would risk the hypothesis that “Easy” in “FakeItEasy” means “ Easy Over Simple ”. The library says this is “easy,” and this is probably the case if you use it with C #. Because it is clearly designed for use with this language. But it is far from “simple” because it uses special syntax tricks with C #, which are hidden from view and do not work in F #.
The specific information you are getting right now is a combination of two things: (1) F # functions do not match C # Func<T,R> , and (2) F # overload resolution rules are different from C #.
There are three CallTo overloads - two of them take Expression<_> , and the third is "everything" by taking an object . In C #, if you call this method with a lambda expression as an argument, the compiler will try your best to convert the lambda expression to Expression<_> and call one of the specialized methods. F #, however, does not do this: F # support for the C # style Expression<_> very limited, primarily focused on LINQ compatibility, and only works when there are no alternatives. Thus, in this case, F # selects CallTo(object) overload.
Next, what will be the argument? F # is a very strict and consistent language. In addition to some special interaction cases, most F # expressions are of a certain type, regardless of the context in which they appear. In particular, an expression of the form fun() -> x will be of type unit -> 'a , where' a is of type x . In other words, this is an F # function.
At run time, the F # functions are represented by the FSharpFunc<T,R> , so the compiler switches to the CallTo(object) method, which will look at it and, not realizing that this is a hell exception.
To fix this, you can make yourself a special version of CallTo (let it be called FsCallTo ) that will force the F # compiler to convert your fun() -> x Expression<_> to Expression<_> , and then use this method instead of of CallTo :
However , as you absolutely correctly noticed, this is too big a problem for mocking the interface, since F # already has a completely statically verifiable, time-free, syntactically nice alternative in the form of object expressions:
let myFake = { new IMyInterface with member this.HeartbeatInterval = 10 member this.HeartbeatInterval with set _ = () }
I would recommend them with them.