使用 FSUnit.Xunit 测试集合

Testing collections with FSUnit.Xunit

我正在尝试使用 FSUnit(特别是它的 Xunit 分支)在 F# 中测试两个集合的相等性,但到目前为止失败得很厉害。

我有一个函数 return 是特定结构的数组,我想测试 returned 数组是否正确。我正在测试的代码是在 C# 中,因此函数不能 return 本机 F# 列表。

我尝试过的最有希望的方法如下:

[<Fact>]
let SimpleTest() = 
    let parser = new ExpressionParser()
    parser.ParseExpression "2" |> should equal [new ParsedItem("2", ParsedItemType.Value)]

...但由于以下原因导致测试失败:

"Message> FSUnit.Xunit+MatchException: Exception of type 'FsUnit.Xunit+MatchException' was thrown. 

Expected value: Equals [(2)]
Actual: was [2]

我可以看出这是因为本机 F# 列表的类型与本机数组不匹配但老实说不知道(我也没有在文档中找到任何内容)如何以不同的方式进行操作(除了事先创建本机数组并一个一个地填充它...)。

我也尝试过其他一些方法,但它们通常甚至无法编译。


PS:我对 F# 和 Xunit 都是全新的,所以我可能遗漏了一些非常明显的东西。

编辑: 在评论中提出了一种实际效果更好的解决方法(比较字符串表示而不是对象本身),虽然我将在我的实际代码中使用它,但我会仍然感谢我上面问题的真正解决方案。

好的,我找到了答案,而且比我想象的要简单。首先,assentation 运行良好,问题出在语法上,我懒得阅读有关如何在 F# 中创建数组的文档,只是猜测而已。

有两处错误。首先 [new ParsedItem("2", ParsedItemType.Value)] 不会创建一个数组,它会创建一个列表。这本身对 FSUnit 的 should equal 来说不是问题,但足以使使用 = 的简单结构相等性测试失败。

第二个错误是我并没有真正与 [new ParsedItem("2", ParsedItemType.Value)] 进行比较,而是与 [new ParsedItem("2", ParsedItemType.Value), new ParsedItem("+", ParsedItemType.Operator), new ParsedItem("3", ParsedItemType.Value)] 进行了比较,实际上创建了一个包含 一对 [=28] 的列表=].而且 - 不出所料 - 并没有很好地断言 :)。

只需阅读文档并了解到应该创建一个数组[|new ParsedItem("2", ParsedItemType.Value); new ParsedItem("+", ParsedItemType.Operator); new ParsedItem("3", ParsedItemType.Value)|] 就解决了这个问题。


无论如何,感谢您的评论和其他答案。虽然他们没有回答我的问题,但他们增加了我对 F# 的了解,并给了我一个如何测试的新想法:)。

尽管您无法从 C# 代码轻松 return F# 列表,但一种选择是 return 数组。它们具有结构相等性,因此您可以简单地比较它们以确定它们是否彼此相等:

open System.Linq

let csharpArray = Enumerable.Range(0, 10).ToArray()
let fsharpArray = [| 0..9 |]

这两个数组相等:

> csharpArray = fsharpArray;;
val it : bool = true

如果你不想 return 数组,你也可以 return IEnumerable<T>,并在 F# 中转换为列表或数组:

> let csharpEnumerable = Enumerable.Range(0, 10);;    
val csharpEnumerable : System.Collections.Generic.IEnumerable<int>

> csharpEnumerable |> Seq.toList = [0..9];;
val it : bool = true

要更全面地介绍使用 F# 进行单元测试,您可能需要 view my Pluralsight course on the topic