FsUnit`应该等于`失败了`Some []`

Min*_*ang 4 f# nunit fsunit

当我使用NUnit 2.6.3运行此FsUnit测试时,

let f xs = Some (List.map ((+) 2) xs)

[<Test>]
let test() =
  f []
  |> should equal (Some [])
Run Code Online (Sandbox Code Playgroud)

我明白了:

Result Message: 
Expected: <Some([])>
  But was:  <Some([])>
Result StackTrace:  
at FsUnit.TopLevelOperators.should[a,a](FSharpFunc`2 f, a x, Object y)
Run Code Online (Sandbox Code Playgroud)

即使消息中的Expected和Actual相同,测试也会失败.发生了什么?

pad*_*pad 8

原因是FsUnit在引擎盖下使用了无类型机制,因此Expected可以object通过类型检查器推断出来(参见Object ystacktrace中的部分).

解决方法是为通用值添加类型注释,即

[<Test>]
let test() =
  f []
  |> should equal (Some ([]: int list))
Run Code Online (Sandbox Code Playgroud)

有几个人被类型提供者中的例如Weird None行为所困扰.

一旦他们不再是类型安全的话,美丽的流畅断言对我来说毫无意义.我建议创建一个类型安全的替代方案:

let shouldEqual (x: 'a) (y: 'a) = 
    Assert.AreEqual(x, y, sprintf "Expected: %A\nActual: %A" x y)
Run Code Online (Sandbox Code Playgroud)