首页 文章

如何使用F#区分联合类型作为TestCase属性参数?

提问于
浏览
3

我试图测试F#函数的返回结果是否符合预期的区分联合情况 . 我正在使用NUnit来创建测试,并且它不喜欢区分联合类型作为 TestCase 参数 . 以下测试用例无法编译:

[<TestCase("RF000123", Iccm.CallType.Request)>]
let ``callTypeFromCallNumber returns expected call type``
    callNumber callType =
    test <@ Iccm.callTypeFromCallNumber callNumber = callType @>

我希望这是NUnit的限制,但我不完全确定 . 我有一个想法解决这个问题,我将发布作为我的答案,但更优雅的解决方案将是很好的 .

如何使用区分的并集案例作为测试用例属性参数?

2 回答

  • 4

    这不是NUnit的限制,而是F#语言(以及C#和VB)的限制:您只能将常量放入属性,而不能放入对象 . Discriminated Unions编译为IL中的对象,因此您无法将它们放入属性中 .

    但是,您可以将枚举放入属性中,因为它们在运行时重新编号 .

    从OP中的示例看, CallType Discriminated Union看起来没有相关数据,因此您可以考虑将设计更改为an enum

    type CallType =
        | Request = 0
        | Incident = 1
        | ChangeManagement = 2
        | Unknown = 3
    

    但是你应该意识到,这使得 CallType 成为一个枚举;它不再是一个被歧视的联盟 . 但是,它应该允许您使用属性中的值 .

  • 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 @>
    

相关问题