F# Observable - 将事件流转换为列表
F# Observable - Converting an event stream to a list
我正在编写一个单元测试来验证从 class 触发的事件。我遵循了标准 "IEvent<_>, Publish, Trigger inside an FSharp type" 模式。
你能推荐 "functional" 实现该目标的方法吗?
以下是我能想到的选项:
- 将事件流转换为字符串列表,并将该列表与预期列表进行比较
- (不确定有没有办法)将预期列表转换成事件流,比较两个流
指向被截断的代码的指针将大有帮助。
谢谢!
编辑 1:回答 Mark 的问题:
这是我目前拥有的:
let expectedFiles = [ "c:\a"
"c:\a" ]
[<Fact>]
let ``Can find files from a folder`` () =
let ad = new FileSearchAdapter()
let foundFiles = ref []
ad.FileFound
|> Observable.scan (fun acc e -> e::acc) []
|> Observable.add (fun acc -> foundFiles := acc)
ad.FindFiles @"c:\a"
Assert.Equal<string list>(expectedFiles, !foundFiles)
我觉得这里的问题是 [a] 引用单元格的使用 [b] observable.add 本质上是覆盖每个事件的引用。
是否有实现相同功能的方法?
事件都是关于副作用的,因此尝试使其全部功能的意义有限。
(是的:您可以构建反应式系统,其中不可变的事件数据流经系统,沿途被过滤和聚合,但在源头,引发事件是副作用。)
考虑到单元测试测试的是独立于其依赖项的单元,测试事件是否正确引发,测试了系统的隔离 'un-functional' 部分,所以我不认为你 以函数式方式完成。
这里有一个更简单的选择:
open System.Collections.Generic
let ``Can find files from a folder`` () =
let ad = new FileSearchAdapter()
let foundFiles = List<string>()
ad.FileFound.Add(fun (sender, args) -> foundFiles.Add args)
ad.FindFiles "c:\a"
let expectedFiles = [ "c:\a"; "c:\a" ]
expectedFiles = (foundFiles |> Seq.toList)
(这个测试函数只是 returns bool
的一个普通函数,但我相信你知道如何将它转换为单元测试。)
我正在编写一个单元测试来验证从 class 触发的事件。我遵循了标准 "IEvent<_>, Publish, Trigger inside an FSharp type" 模式。
你能推荐 "functional" 实现该目标的方法吗?
以下是我能想到的选项:
- 将事件流转换为字符串列表,并将该列表与预期列表进行比较
- (不确定有没有办法)将预期列表转换成事件流,比较两个流
指向被截断的代码的指针将大有帮助。
谢谢!
编辑 1:回答 Mark 的问题:
这是我目前拥有的:
let expectedFiles = [ "c:\a"
"c:\a" ]
[<Fact>]
let ``Can find files from a folder`` () =
let ad = new FileSearchAdapter()
let foundFiles = ref []
ad.FileFound
|> Observable.scan (fun acc e -> e::acc) []
|> Observable.add (fun acc -> foundFiles := acc)
ad.FindFiles @"c:\a"
Assert.Equal<string list>(expectedFiles, !foundFiles)
我觉得这里的问题是 [a] 引用单元格的使用 [b] observable.add 本质上是覆盖每个事件的引用。
是否有实现相同功能的方法?
事件都是关于副作用的,因此尝试使其全部功能的意义有限。
(是的:您可以构建反应式系统,其中不可变的事件数据流经系统,沿途被过滤和聚合,但在源头,引发事件是副作用。)
考虑到单元测试测试的是独立于其依赖项的单元,测试事件是否正确引发,测试了系统的隔离 'un-functional' 部分,所以我不认为你 以函数式方式完成。
这里有一个更简单的选择:
open System.Collections.Generic
let ``Can find files from a folder`` () =
let ad = new FileSearchAdapter()
let foundFiles = List<string>()
ad.FileFound.Add(fun (sender, args) -> foundFiles.Add args)
ad.FindFiles "c:\a"
let expectedFiles = [ "c:\a"; "c:\a" ]
expectedFiles = (foundFiles |> Seq.toList)
(这个测试函数只是 returns bool
的一个普通函数,但我相信你知道如何将它转换为单元测试。)