单元测试:'[] |>应该等于List.empty'不能按预期工作

Gee*_*hem 1 f# xunit pattern-matching fsunit

我有以下代码,测试失败:

open Xunit
open FsUnit.Xunit

let rec openOrSenior xs = 
    match xs with
    | head :: tail when fst head >= 55 && snd head >= 7 -> "Senior" :: openOrSenior tail
    | head :: tail -> "Open" :: openOrSenior tail
    | [] -> []

[<Fact>]
let ``empty input gives empty result``() =
    openOrSenior [] |> should equal List.empty
Run Code Online (Sandbox Code Playgroud)

测试失败,出现以下匹配错误

FsUnit.Xunit + MatchException:抛出了类型'FsUnit.Xunit + MatchException'的异常.预期:等于[]
实际:是[]

Fyo*_*kin 7

这个答案只是为了澄清这背后的原因.事实证明,评论太长了.

这是一种类型不匹配的情况.这两个值[],并[]在打印时,但实际上有不同的类型看起来是一样的:"实际"值string list,但"预期"值obj list.

发生这种情况是因为它List是通用的,并且should equal不要求"预期"和"实际"具有相同的类型,从而防止类型推断被踢入.例如,这编译:

5 |> should equal "abc"
Run Code Online (Sandbox Code Playgroud)

当然,它会在运行时失败,很好地向您展示这些值实际上并不相同.

但是如果你的一个值在返回类型中是通用的:

let a: int list = []
a |> should equal []
Run Code Online (Sandbox Code Playgroud)

然后缺少类型推断意味着这个值最终会有类型obj,因此严格来说不等于具有不同类型的另一个值"相等".


Bar*_*cki 6

equal在FsUnit做一些花哨的比赛be只是身份功能. 这是链接源

如果您使用以下情况,您的支票将没事:

|> should be Empty
Run Code Online (Sandbox Code Playgroud)