When I run this FsUnit test with NUnit 2.6.3,
let f xs = Some (List.map ((+) 2) xs)
[<Test>]
let test() =
f []
|> should equal (Some [])
I get:
Result Message:
Expected: <Some([])>
But was: <Some([])>
Result StackTrace:
at FsUnit.TopLevelOperators.should[a,a](FSharpFunc`2 f, a x, Object y)
The test fails even though the Expected and Actual in the message are the same. What happened?
The reason is that FsUnit uses untyped mechanism under the hood so Expected
is inferred as object
by the type checker (see the Object y
part in the stacktrace).
A workaround is to add type annotation for generic values i.e.
[<Test>]
let test() =
f []
|> should equal (Some ([]: int list))
Several people have been bitten by this e.g. Weird None behaviour in type providers.
Beauty of fluent assertions is pointless to me once they're no longer type-safe. I suggest to create a type-safe alternative:
let shouldEqual (x: 'a) (y: 'a) =
Assert.AreEqual(x, y, sprintf "Expected: %A\nActual: %A" x y)