我认为它与使用times论证有关Verify().
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())
Run Code Online (Sandbox Code Playgroud)
异常消息:
System.ArgumentException:类型'System.Void'的表达式不能用于'Microsoft.FSharp.Core.Unit'类型的构造函数参数
Moq的Verify方法有很多重载,如果没有注释,F#默认会将你指定的表达式解析为期望Func<IService,'TResult>where 'TResult为unit 的重载,这解释了运行时的失败.
你想要做的是明确使用过载Verify它接受一个Action.
一种选择是使用Moq.FSharp.Extensions项目(在Nuget上作为一个包提供),其中包括添加2个扩展方法VerifyFunc,VerifyAction并使得更容易将F#函数解析为Moq的基于C#Action或Func参数:
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())
Run Code Online (Sandbox Code Playgroud)
另一个选择是使用Foq,一个专门为F#用户设计的Moq 模拟库(也可作为Nuget包提供):
open Foq
[<Test>]
let ``No worries`` () =
let mock = Mock.Of<IService>()
Mock.Verify(<@ mock.DoStuff() @>, never)
Run Code Online (Sandbox Code Playgroud)