如何在 F# 中创建一个 Action<T>?

9
我正在使用Moq框架进行单元测试,希望能够传递Action以记录void方法的日志。
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)

这段代码出现了以下错误:

System.InvalidCastException:无法将类型为“System.Linq.Expressions.MethodCallExpressionN”的对象强制转换为类型“System.Linq.Expressions.Expression1[System.Action1[log4net.ILog]]”。

我可以使用以下方法打印出类型:

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

这段代码输出的是:

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

那么,我该如何创建一个 Action?


1
Moq在F#中可能不是一个好主意。 - Mauricio Scheffer
1
是的,在F#中我们使用Foq - 请参阅http://trelford.com/blog/post/Foq.aspx和http://trelford.com/blog/post/FoqItEasy.aspx(非常容易从Moq过渡)。 - Ruben Bartelink
2个回答

14
LINQ表达式在F# 3中得到了完全支持,因此您现在可以将一个lambda表达式作为一个Action传递给Moq。
let mock = Mock<ILog>()
mock.Verify(fun (log:ILog) -> log.Info(It.IsAny<string>()))

5

尝试:

let quot = <@ new Action<_>(fun (mock:ILog) -> mock.Info(It.IsAny<string>)) @>

这样创建的操作是正确的,但对于 Moq 仍然没有起作用。 - YonahW

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接