我正在尝试使用FSUnit(特别是它的Xunit分支)在F#中测试两个集合的相等性,但到目前为止都失败了。
我有一个函数返回某些结构的数组,并希望测试返回的数组是否正确。我正在测试的代码是在C#中,因此函数无法返回本机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都是全新的,所以我可能会遗漏一些绝对明显的东西。编辑:在评论中建议实际效果更好的解决方法(比较字符串表示而不是对象本身),虽然我将在实际代码中使用它,但我仍然感谢真正的解决方案我上面的问题。
答案 0 :(得分:2)
好的,我找到了答案,它比我想象的要简单。首先,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)]
相比并没有真正比较,而且实际上创建了一个包含 one touple 的列表。而且 - 毫不奇怪 - 没有说得好:)。
只需阅读文档并了解应该创建一个数组[|new ParsedItem("2", ParsedItemType.Value); new ParsedItem("+", ParsedItemType.Operator); new ParsedItem("3", ParsedItemType.Value)|]
就可以解决问题。
无论如何,感谢评论和其他答案。虽然他们没有回答我的问题,但他们增加了我对F#的了解,并给了我一个新的想法如何测试:)。
答案 1 :(得分:2)
虽然您无法从C#代码中轻松返回F#列表,但一种选择是返回数组。它们具有结构相等性,因此您可以简单地比较它们以确定它们是否彼此相等:
open System.Linq
let csharpArray = Enumerable.Range(0, 10).ToArray()
let fsharpArray = [| 0..9 |]
这两个数组是相同的:
> csharpArray = fsharpArray;;
val it : bool = true
如果您不想返回数组,也可以返回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。