使用 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。
我正在尝试使用 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。