为什么从F#调用Moq抛出异常?

时间:2015-05-09 15:57:17

标签: f# moq

我认为这与在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())

异常消息:

  

System.ArgumentException:'System.Void'类型的表达式不能用于'Microsoft.FSharp.Core.Unit'类型的构造函数参数

1 个答案:

答案 0 :(得分:6)

Moq的Verify方法有很多重载,如果没有注释,F#默认会将您指定的表达式解析为期望Func<IService,'TResult> 'TResult为{1}}的单位,这解释了运行时的失败。

您要做的是明确使用Verify的重载,该重载需要Action

一种选择是使用Moq.FSharp.Extensions项目(在Nuget上提供),其中包括添加2种扩展方法VerifyFunc&amp; 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 package):

open Foq

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