FsUnit `should equal` fails on `Some []`
Asked Answered
D

2

5

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?

Drink answered 2/6, 2014 at 8:2 Comment(2)
This looks like FsUnit has modified the semantics of = - running equivalent code but using = instead of should equal returns what you would expect.Constabulary
See #5667872 - Unquote always does what I mean and much more besidesScenic
T
9

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)
Tinnitus answered 2/6, 2014 at 9:21 Comment(1)
This is available in FsUnitTyped: fsprojects.github.io/FsUnit/FsUnitTyped.htmlDander
V
4

This is because your two empty lists are of different types. See the types of actual and expected in this version of your test:

[<Test>]
let test() =
  let expected = Some []
  let actual = f []
  actual |> should equal expected

expected is 'a list option and actual is int list option, so they are not equal.

If you give the compiler some hints about the expected result then it will work.

[<Test>]
let test() =
  f []
  |> should equal (Some List.empty<int>)
Vanthe answered 2/6, 2014 at 9:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.