Why is Moq checking the calling method throws an exception?
I cannot convey this piece of code.
[<Test>]
member public this.Test() =
let mock = new Mock<IList<string>>()
let mockObj = mock.Object
mockObj.Add("aaa")
mock.Verify(fun m -> m.Add(It.IsAny<string>()), Times.Once())
An exception:
System.ArgumentException : Expression of type 'System.Void' cannot be used for constructor parameter of type 'Microsoft.FSharp.Core.Unit'
I believe it has something to do with F # not inferring the correct data type of the labda expression, but I don't know how to fix it.
source to share
You are correct, this is an issue with F # type inference when calling an overloaded method that takes an Action or Func.
One option is to download Moq.FSharp.Extensions from Nuget and change yours Verify
to explicit VerifyAction
, i.e.
open Moq.FSharp.Extensions
type MyTests() =
[<Test>]
member public this.Test() =
let mock = new Mock<IList<string>>()
let mockObj = mock.Object
mockObj.Add("aaa")
mock.VerifyAction((fun m -> m.Add(any())), Times.Once())
Under the covers, the Moq.FSharp.Extensions files simply define an extension method VerifyAction
that it accepts just Action
to avoid ambiguity:
type Moq.Mock<'TAbstract> when 'TAbstract : not struct with
member mock.VerifyAction(expression:Expression<Action<'TAbstract>>) =
mock.Verify(expression)
Another option is to use Foq , a mocking library with a similar API to Moq but designed specifically for use with F #, also available through Nuget :
[<Test>]
member public this.Test() =
let mock = Mock.Of<IList<string>>()
mock.Add("aaa")
Mock.Verify(<@ mock.Add(any()) @>, once)
source to share