我正在使用FsUnit.Xunit
。我的以下测试用例失败:
[<Fact>]
let ``Initialization of DFF`` () =
dff Seq.empty Seq.empty |> should equal (seq {Zero})
测试失败的是:
Message:
FsUnit.Xunit+MatchException : Exception of type 'FsUnit.Xunit+MatchException' was thrown.
Expected: Equals seq [Zero]
Actual: seq [Zero]
Stack Trace:
That.Static[a](a actual, IMatcher`1 matcher)
Signal.Initialization of DFF() line 11
如果测试是这样的话,我会得到同样的错误:
[<Fact>]
let ``Initialization of DFF`` () =
dff Seq.empty Seq.empty |> should equal (Seq.singleton Zero)
我从未使用FsUnit.Xunit
测试过序列的相等性,所以我很困惑发生了什么。我什至不确定失败消息告诉我什么,因为它似乎在说预期和实际是相同的。我可以通过将序列转换为列表来使其正常工作,但最好不必这样做。
有人可以解释一下这是怎么回事吗?看来我不理解错误消息,因此可能涉及 Equals
和比较序列值(文字?)。谢谢。
能够重现的源代码(我认为这就是一切):
type Bit =
| Zero
| One
type Signal = seq<Bit>
let Nand a b =
match a, b with
| Zero, Zero -> One
| Zero, One -> One
| One, Zero -> One
| One, One -> Zero
let Not input =
Nand input input
let And a b =
Not (Nand a b)
let Or a b =
Nand (Not a) (Not b)
let private liftToSignal1 op (signal: Signal) : Signal =
Seq.map op signal
let private liftToSignal2 op (signalA: Signal) (signalB: Signal) : Signal =
Seq.map2 op signalA signalB
let Not' = liftToSignal1 Not
let And' = liftToSignal2 And
let Or' = liftToSignal2 Or
let rec dff data clock : Signal =
seq {
yield Zero
yield! Or' (And' data clock)
(And' (dff data clock) (Not' clock))
}
最佳答案
这是结构平等与引用平等的问题。
在 F# 中 seq { 'a' } = seq { 'a' }//false
但 [ 'a' ] = [ 'a' ]//true
由于 seq
是 IEnumerable
并且不支持结构相等(或比较)。
列表(和其他类似 F# 容器的类型)更加“智能”,即,如果所包含的对象支持结构相等/比较,它们就支持结构相等/比较:
[ {| foo = StringComparison.Ordinal; bar = Some(1.23) |} ] =
[ {| foo = StringComparison.Ordinal; bar = Some(1.23) |} ] // true
但如果它们包含任何不包含以下内容的内容,则不要:
[ box(fun() -> 3) ] = [ box(fun() -> 3) ]//false
因此,为了使测试正常进行,请添加一个 List.ofSeq
:
dff Seq.empty Seq.empty |> List.ofSeq |> should equal [ Zero ]
关于.net-core - 将 `should equal` 与 F# 和 FsUnit 中的序列一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73740141/