我试图测试F#函数的返回结果是否符合预期的区分联合情况。我正在使用NUnit来创建测试,并且它不喜欢区分的联合类型作为TestCase
参数。以下测试用例无法编译:
[<TestCase("RF000123", Iccm.CallType.Request)>]
let ``callTypeFromCallNumber returns expected call type``
callNumber callType =
test <@ Iccm.callTypeFromCallNumber callNumber = callType @>
我希望这是NUnit的限制,但我不完全确定。我有一个想法可以解决这个问题,我将发布作为我的答案,但更优雅的解决方案将会很好。
如何使用区分联合案例作为测试用例属性参数?
答案 0 :(得分:4)
这不是NUnit的限制,而是F#语言(以及C#和VB)的限制:您只能将常量放入属性,而不是对象。 Discriminated Unions编译为IL中的对象,因此您无法将它们放入属性中。
你可以将枚举放入属性中,因为它们是常量(它们是运行时的数字)。
从OP中的示例看,CallType
歧视联盟似乎没有相关数据,因此您可以考虑将设计更改为an enum:
type CallType =
| Request = 0
| Incident = 1
| ChangeManagement = 2
| Unknown = 3
但是你应该意识到,这会使CallType
成为一个枚举;它不再是一个被歧视的联盟。但是,它应该允许您使用属性中的值。
答案 1 :(得分:2)
这是我解决问题的方法。它工作得很好,虽然我发现它有点转移。我只是使用字符串代替类型,然后使用模式匹配转换为断言中的实际类型。
[<TestCase("RF000123", "Request")>]
[<TestCase("IM000123", "Incident")>]
[<TestCase("CM000123", "ChangeManagement")>]
[<TestCase("AR000123", "Unknown")>]
let ``callTypeFromCallNumber returns expected call type``
callNumber callType =
test <@ Iccm.callTypeFromCallNumber callNumber = match callType with
| "Request" -> Iccm.CallType.Request
| "Incident" -> Iccm.CallType.Incident
| "ChangeManagement" -> Iccm.CallType.ChangeManagement
| _ -> Iccm.CallType.Unknown @>