3

我是 F# 的新手,我正在通过一些练习来学习这门语言。我目前正在尝试做的是为自定义 Castle.Windsor 设施编写单元测试,并且我正在尝试模拟内核以引发“ComponentRegistered”事件。

我使用的工具是 FsUnit/xUnit/Foq。

我的代码:

let event = Event<_,_>()

let kernel = Mock<IKernel>()
    .SetupEvent(fun k -> <@ k.ComponentRegistered @>)
    .Publishes(event.Publish)
    .Create()

错误信息:

错误 4 事件“ComponentRegistered”具有非标准类型。如果此事件是用另一种 CLI 语言声明的,您可能需要使用该事件的显式 add_ComponentRegistered 和 remove_ComponentRegistered 方法来访问此事件。如果此事件在 F# 中声明,则将事件类型设为“IDelegateEvent< >”或“IEvent< ,_>”的实例化。C:\Workbench\EvilDev\evildev.commons\Tests\EvilDev.Commons.Windsor.Tests\Auto Resolver Facility Specification.fs 35 53 EvilDev.Commons.Windsor.Tests

如何从 F# 模拟/触发此类事件?

4

1 回答 1

3

可以使用DelegateEvent指定这种类型的事件:

let event = DelegateEvent<ComponentDataDelegate>()
let kernel = 
    Mock<IKernel>()
        .SetupEventByName("ComponentRegistered")            
        .Publishes(event.Publish)
        .Create()    
kernel.add_ComponentRegistered(fun _ _ -> 
    printf "Bingo"
)
event.Trigger([|"x";Mock.Of<IHandler>()|])

可以使用Type.GetEvent方法通过反射发现事件的添加和删除处理程序。

我扩展了 Foq API 以允许按名称指定事件,以便您可以指定事件名称(未键入)以解决非标准事件类型编译器错误。

添加新的 SetupEventByName 方法的更改集已提交。如果您现在需要这个,您可以从源代码构建或简单地将最新的Foq.fs添加到您的项目中。这个功能将在 Foq 1.5 中,我将在第二天左右尝试推送。

于 2013-12-28T23:23:38.323 回答