I am using F# type definitions to prevent hard dependencies between my functions, for example
type IType1 = int -> int
type IType2 = int-> string
let func1 (i : int) : int = i * i
let func2 (i : int) : string = i |> string
let higherFunc (dep1 : IType1) (dep2 : IType2) (input : int) : string =
input |> dep1 |> dep2
let curriedFunc = higherFunc func1 func2
let x = curriedFunc 2
output x : "4"
Obviously this is quite contrived and simple but imagine the dependencies are a parser and a sorter or whatever. Smaller grains of functionality that I am composing.
I am trying to use Foq to help with my unit test fixtures. This is my first week using F# properly and I am having a hard time trying to work out how to configure a mock of these types.
Two things are worth mentioning:
1 - I can make it work if I use abstract classes, but I don't want to do this as it's so much more hassle for exactly the same end result. For example
type IType1 =
abstract member doSomething : int -> int
type func1 () =
interface IType1 with
member this.doSomething (i: int) = i * i
allows me to set up a mock like
let mT1= Mock.With (fun (x : IType1) -> <@ x.doSomething(any()) --> 5 @>)
but I really don't want to have to do this.
2 - If I just use
type IType1 = int -> int
let mT1 = Mock.Of<IType1>()
then I get back a valid value, but if I try to configure it in any way like
let mT1= Mock<IType1>.With (fun x -> <@ x(any()) --> 5 @>)
or
let mT1= Mock<IType1>.With (fun x -> <@ any() --> 5@>)
then I get an exception of
System.NotSupportedException : Expected standard function application: Call
or
System.NotSupportedException : Expected standard function application: ValueWithName
I am hoping that I'm just being stupid with the syntax and that it is possible to do what I want. I have tried every variation I can think of, including variations of .Setup(conditions).Create(), and I can't find any examples in the source.
I can obviously easily make my own mocks like
let mT1 (i : int) : int = 5
as anything which fits that int -> int signature will be valid, but then if I want to check that the function was passed a certain value for i I have to put in a logging step etc etc.. It would just be nice to have Foq to do some of the heavy lifting.
Edit I just noticed that the root Mock object has 'requires reference type' in its signature ( i.e. Mock<'TAbstract(requires reference type)> ) - does that mean I have no chance of mocking values? How come it manages it if I don't configure the mock?