为什么 Moq 验证方法调用会抛出异常?
Why Moq verify method call throws exception?
我无法让这段代码通过。
[<Test>]
member public this.Test() =
let mock = new Mock<IList<string>>()
let mockObj = mock.Object
mockObj.Add("aaa")
mock.Verify(fun m -> m.Add(It.IsAny<string>()), Times.Once())
我得到异常:
System.ArgumentException : Expression of type 'System.Void' cannot be used for constructor parameter of type 'Microsoft.FSharp.Core.Unit'
我认为这与 F# 无法正确推断 labda 表达式的数据类型有关,但我不知道如何解决。
你是对的,这是调用接受 Action 或 Func 的重载方法时 F# 类型推断的问题。
一种选择是下载 Moq.FSharp.Extensions from Nuget 并将您的 Verify
更改为明确的 VerifyAction
,即
open Moq.FSharp.Extensions
type MyTests() =
[<Test>]
member public this.Test() =
let mock = new Mock<IList<string>>()
let mockObj = mock.Object
mockObj.Add("aaa")
mock.VerifyAction((fun m -> m.Add(any())), Times.Once())
在幕后,Moq.FSharp.Extensions 只是定义了一个扩展方法 VerifyAction
,它只需要一个 Action
来避免歧义:
type Moq.Mock<'TAbstract> when 'TAbstract : not struct with
member mock.VerifyAction(expression:Expression<Action<'TAbstract>>) =
mock.Verify(expression)
另一种选择是使用 Foq, a mocking library with a similar API to Moq but designed specifically for use from F#, also available via Nuget:
[<Test>]
member public this.Test() =
let mock = Mock.Of<IList<string>>()
mock.Add("aaa")
Mock.Verify(<@ mock.Add(any()) @>, once)
我无法让这段代码通过。
[<Test>]
member public this.Test() =
let mock = new Mock<IList<string>>()
let mockObj = mock.Object
mockObj.Add("aaa")
mock.Verify(fun m -> m.Add(It.IsAny<string>()), Times.Once())
我得到异常:
System.ArgumentException : Expression of type 'System.Void' cannot be used for constructor parameter of type 'Microsoft.FSharp.Core.Unit'
我认为这与 F# 无法正确推断 labda 表达式的数据类型有关,但我不知道如何解决。
你是对的,这是调用接受 Action 或 Func 的重载方法时 F# 类型推断的问题。
一种选择是下载 Moq.FSharp.Extensions from Nuget 并将您的 Verify
更改为明确的 VerifyAction
,即
open Moq.FSharp.Extensions
type MyTests() =
[<Test>]
member public this.Test() =
let mock = new Mock<IList<string>>()
let mockObj = mock.Object
mockObj.Add("aaa")
mock.VerifyAction((fun m -> m.Add(any())), Times.Once())
在幕后,Moq.FSharp.Extensions 只是定义了一个扩展方法 VerifyAction
,它只需要一个 Action
来避免歧义:
type Moq.Mock<'TAbstract> when 'TAbstract : not struct with
member mock.VerifyAction(expression:Expression<Action<'TAbstract>>) =
mock.Verify(expression)
另一种选择是使用 Foq, a mocking library with a similar API to Moq but designed specifically for use from F#, also available via Nuget:
[<Test>]
member public this.Test() =
let mock = Mock.Of<IList<string>>()
mock.Add("aaa")
Mock.Verify(<@ mock.Add(any()) @>, once)