为什么从F#调用Moq会引发异常?

4
我认为这与在Verify()上使用times参数有关。
open NUnit.Framework
open Moq

type IService = abstract member DoStuff : unit -> unit

[<Test>]
let ``Why does this throw an exception?``() =
    let mockService = Mock<IService>()
    mockService.Verify(fun s -> s.DoStuff(), Times.Never())

异常信息:

System.ArgumentException:无法将类型为“System.Void”的表达式用作类型为“Microsoft.FSharp.Core.Unit”的构造函数参数

1个回答

7

Moq的Verify方法有许多重载,在没有注释的情况下,F#默认会将您指定的表达式解析为期望一个Func<IService,'TResult>类型的重载,其中'TResult为unit,这解释了运行时的失败。

您需要明确使用接受ActionVerify重载。

一种选择是使用Nuget上可用的Moq.FSharp.Extensions项目(作为软件包提供),其中包括添加了两个扩展方法VerifyFunc VerifyAction,使得解析F#函数到Moq的基于C#的ActionFunc参数更加容易:

open NUnit.Framework
open Moq
open Moq.FSharp.Extensions

type IService = abstract member DoStuff : unit -> unit

[<Test>]
let ``Why does this throw an exception?``() =
   let mockService = Mock<IService>()
   mockService.VerifyAction((fun s -> s.DoStuff()), Times.Never())

另一个选择是使用Foq,这是一个专为F#用户设计的类似Moq的模拟库(也可作为Nuget包使用):

open Foq

[<Test>]
let ``No worries`` () =
  let mock = Mock.Of<IService>()
  Mock.Verify(<@ mock.DoStuff() @>, never)

1
我认为你的意思是NuGet包添加了VerifyFunc和VerifyAction扩展方法,而不是重载。 - Andy

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