简体   繁体   English

使用FSUnit.Xunit测试集合

[英]Testing collections with FSUnit.Xunit

I'm trying to test equality of two collections in F# using FSUnit (specifically its Xunit branch) but failing horribly so far. 我正在尝试使用FSUnit(特别是它的Xunit分支)在F#中测试两个集合的相等性,但到目前为止却失败了。

I have a function that returns an array of certain structs and would like to test whether the returned array is correct. 我有一个函数,该函数返回某些结构的数组,并想测试返回的数组是否正确。 The code I'm testing is in C# so it so the function can't return native F# lists. 我正在测试的代码在C#中,因此该函数无法返回本地F#列表。

The most promising approach I've tried is following: 我尝试过的最有前途的方法如下:

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

...but it results in the the test failing because of: ...但是由于以下原因导致测试失败:

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

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

I can see that it's because the type of native F# list doesn't match a native array but have honestly no idea (nor have I found anything in documentation) how to do it differently (other then creating native array beforehand and populating it one by one...). 我可以看到这是因为本机F#列表的类型与本机数组不匹配,但是老实说不知道(我也没有在文档中找到任何东西)如何做不同的操作(其他方法是事先创建本机数组并按以下方式填充它)一...)。

I've also tried some other approaches but they usually wouldn't even compile. 我也尝试了其他方法,但是它们通常甚至都不会编译。


PS: I'm completely new to both F# and Xunit so I might be missing something absolutely obvious. PS:我是F#和Xunit的新手,所以我可能会错过一些绝对明显的东西。

EDIT: A workaround that actually works better was suggested in comments (comparing string representations instead of the objects themselves) and while I will use that in my actual code I'd still appreciate a true solution to my problem above. 编辑:在注释(比较字符串表示形式而不是对象本身)中提出了一种实际上更好用的解决方法,尽管我将在我的实际代码中使用它,但我仍然很欣赏上述问题的真正解决方案。

Ok, I've found the answer and it's simpler than I thought it'd be. 好的,我已经找到了答案,而且比我想的要简单。 First off the assentation works well the problem was in syntax and me not bothering to read the documentation on how to create an array in F# and just guessing it. 首先,理解很好,问题出在语法上,我不必费心去阅读有关如何在F#中创建数组的文档,而只是猜测一下。

There were two things wrong. 有两件事是错误的。 First [new ParsedItem("2", ParsedItemType.Value)] doesn't create an array it creates a list. 首先[new ParsedItem("2", ParsedItemType.Value)]不创建数组,而是创建一个列表。 That in itself wouldn't be a problem for FSUnit's should equal but it's enough to make simple structural equality test using = fail. 对于FSUnit should equal这本身不是问题,但足以使用= fail进行简单的结构相等性测试。

The second thing that was wrong was that I didn't really compare with [new ParsedItem("2", ParsedItemType.Value)] I compared with [new ParsedItem("2", ParsedItemType.Value), new ParsedItem("+", ParsedItemType.Operator), new ParsedItem("3", ParsedItemType.Value)] and that actually creates a list containing one touple . 错误的第二件事是我没有真正与[new ParsedItem("2", ParsedItemType.Value)]进行比较,而与[new ParsedItem("2", ParsedItemType.Value), new ParsedItem("+", ParsedItemType.Operator), new ParsedItem("3", ParsedItemType.Value)]并实际上创建一个包含一个touple的列表。 And that - unsurprisingly - didn't assert well :). 而且-毫不奇怪-并没有很好地断言:)。

Simply reading the documentation and learning that an array is supposed to be created [|new ParsedItem("2", ParsedItemType.Value); new ParsedItem("+", ParsedItemType.Operator); new ParsedItem("3", ParsedItemType.Value)|] 只需阅读文档并了解应该创建一个数组[|new ParsedItem("2", ParsedItemType.Value); new ParsedItem("+", ParsedItemType.Operator); new ParsedItem("3", ParsedItemType.Value)|] [|new ParsedItem("2", ParsedItemType.Value); new ParsedItem("+", ParsedItemType.Operator); new ParsedItem("3", ParsedItemType.Value)|] [|new ParsedItem("2", ParsedItemType.Value); new ParsedItem("+", ParsedItemType.Operator); new ParsedItem("3", ParsedItemType.Value)|] fixed the issue. [|new ParsedItem("2", ParsedItemType.Value); new ParsedItem("+", ParsedItemType.Operator); new ParsedItem("3", ParsedItemType.Value)|]解决了该问题。


Anyway, thanks for the comments and the other answer. 无论如何,感谢您的评论和其他答复。 Though they didn't answer my question they increased my knowledge about F# and gave me a new idea how to test :). 尽管他们没有回答我的问题,但他们增加了我对F#的了解,并给了我一个如何测试的新想法:)。

Although you can't easily return F# lists from your C# code, one option is to return arrays. 尽管您不能轻易地从C#代码中返回F#列表,但一种选择是返回数组。 These have structural equality, so you can simply compare them to determine if they are equal to each other: 它们具有结构相等性,因此您可以简单地比较它们以确定它们是否彼此相等:

open System.Linq

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

These two arrays are equal: 这两个数组相等:

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

If you don't want to return arrays, you can also return IEnumerable<T> , and convert to either lists or arrays in F#: 如果您不想返回数组,也可以返回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

For a more comprehensive to introduction to unit testing with F#, you may want to view my Pluralsight course on the topic . 有关使用F#进行单元测试的更全面介绍,您可能需要查看有关该主题的Pluralsight课程

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM