9

I am using the Moq framework for unit testing and would like to be able to pass in Action for logging void methods.

let log = new Mock<ILog>()
let quot = <@ fun (mock:ILog) -> mock.Info(It.IsAny<string>) @>  
let expr = (quot.ToLinqExpression() :?> Expression<Action<ILog>>)
log.Verify(expr)

This code fails with the following error:

System.InvalidCastException : Unable to cast object of type 'System.Linq.Expressions.MethodCallExpressionN' to type 'System.Linq.Expressions.Expression1[System.Action1[log4net.ILog]]'.

I can print the type out using

printfn "%s" (quot.Type.ToString())

which outputs

Microsoft.FSharp.Core.FSharpFunc`2[log4net.ILog,Microsoft.FSharp.Core.Unit]

So, how can I create an Action?

Guvante
  • 18,775
  • 1
  • 33
  • 64
YonahW
  • 15,790
  • 8
  • 42
  • 46

2 Answers2

14

LINQ Expressions are fully supported in F# 3, so you can now pass an Action to Moq as a lambda expression:

let mock = Mock<ILog>()
mock.Verify(fun (log:ILog) -> log.Info(It.IsAny<string>()))
Phillip Trelford
  • 6,513
  • 25
  • 40
5

Try:

let quot = <@ new Action<_>(fun (mock:ILog) -> mock.Info(It.IsAny<string>)) @>
Daniel
  • 47,404
  • 11
  • 101
  • 179