代码之家  ›  专栏  ›  技术社区  ›  Scott Nimrod

如何忽略FsUnit断言中歧视工会案例的价值?

  •  5
  • Scott Nimrod  · 技术社区  · 8 年前

    如何忽略FsUnit断言中歧视工会案例的价值?

    例如:

    type TransactionAttempt = { 
        Deposited:float
        Requires:float 
    }
    
    type RequestResult =
        | Denied of TransactionAttempt
        | Granted of Product
    

    在我的测试中,我想这样做:

    let display = balance |> select Pepsi
    display |> should equal Denied
    

    我不介意这样做:

    display |> should equal (Denied _)
    

    然而,我不得不这样做:

    display |> should equal (Denied {Deposited=0.25; Requires=1.00})
    

    因此,我只想知道它是否被拒绝了。我不在乎细节。

    [<Test>]
    let ``Vending machine reflects more money required for selection``() =
       // Setup
       let balance = Quarter |> insert []
    
       // Test
       let display = balance |> select Pepsi
    
       // Verify
       display |> should equal (Denied {Deposited=0.25; Requires=1.00})
    

    功能如下:

    let select product balance =
        let attempt = { Deposited=balance
                        Requires=product |> getPrice }
    
        let paidInFull = attempt.Deposited >= attempt.Requires
    
        if not paidInFull then 
            Denied attempt
        else Granted product
    

    以下是整个域:

    module Machine
    
    type Deposit =
        | Nickel
        | Dime
        | Quarter
        | OneDollarBill
        | FiveDollarBill
    
    type TransactionAttempt = { 
        Deposited:float
        Requires:float 
    }
    
    type State =
        | OutOfService
        | PaymentReceived of Deposit
        | WaitingForSelection
        | NotPaidInFull of TransactionAttempt
    
    type Product =
        | Pepsi
        | Coke
        | Sprite
        | MountainDew
    
    type RequestResult =
        | Denied of TransactionAttempt
        | Granted of Product
    
    (* Functions *)
    open System
    
    let display = function
        | OutOfService            -> "Out of Service"
        | WaitingForSelection     -> "Make selection"
        | NotPaidInFull attempt   -> sprintf "%s Required" ((attempt.Requires - attempt.Deposited).ToString("C2"))
        | PaymentReceived deposit -> match deposit with
                                     | Nickel         -> "5¢"
                                     | Dime           -> "10¢"
                                     | Quarter        -> "25¢"
                                     | OneDollarBill  -> "$1.00"
                                     | FiveDollarBill -> "$5.00"
    
    let getBalance coins =
        coins |> List.fold (fun acc d -> match d with
                                         | Nickel         -> acc + 0.05
                                         | Dime           -> acc + 0.10
                                         | Quarter        -> acc + 0.25
                                         | OneDollarBill  -> acc + 1.00
                                         | FiveDollarBill -> acc + 5.00) 0.00
    let insert balance coin =
        coin::balance |> getBalance
    
    let getPrice = function
        | Pepsi       -> 1.00
        | Coke        -> 1.00
        | Sprite      -> 1.00
        | MountainDew -> 1.00
    
    let select product balance =
        let attempt = { Deposited=balance
                        Requires=product |> getPrice }
    
        let paidInFull = attempt.Deposited >= attempt.Requires
    
        if not paidInFull then 
            Denied attempt
        else Granted product
    
    1 回复  |  直到 8 年前
        1
  •  10
  •   rmunn    8 年前

    let isDenied du =
        match du with
        | Denied _ -> true
        | _ -> false
    

    或者从那以后 let f x = match x with ... 等于 let f = function ... ,可能是:

    let isDenied = function Denied _ -> true | _ -> false
    

    然后您的测试看起来像:

    display |> isDenied |> should be True
    

    请注意 True ,大写T,是一个限制条件。如果将其与布尔值进行比较,则

    display |> isDenied |> should equal true
    

    如果您发现必须编写大量这些自定义谓词,可能有一个更通用的解决方案,涉及为NUnit或XUnit或您在后端使用的任何测试框架编写自定义约束。但作为F#的新手,您可能应该先使用简单的解决方案,然后再进行推广。

    附言。如果您决定编写自定义约束,请查看 https://github.com/fsprojects/FsUnit/blob/master/src/FsUnit.NUnit/FsUnit.fs (如果您正在使用NUnit)或 https://github.com/fsprojects/FsUnit/blob/master/src/FsUnit.Xunit/FsUnit.fs (如果您正在使用XUnit)以获得灵感。