0

私はF#を学ぼうとしていて、いくつかの簡単なクラスで遊んでいますが、これらは期待どおりに動作していません。

私はいくつかの単純な基本を誤解しているに違いありません。この質問が基本的すぎる場合はお詫びしますが、助けていただければ幸いです。

とにかく、私は初めてテスト駆動開発アプローチを適用しましたが、今ではこれの利点をよりよく理解しています。

次のソースコードの調査:

  1. ユーティリティ関数(optionIntTo_s)を定義します。
  2. クラスTUnitTesterを定義します-その目的はユニットテストを支援することです。
  3. 実験的なクラスTOrderItemを定義します。これは可変オプションフィールドのfquantityをラップします(SQL nullまたは整数値を表します)。
  4. TOrderItemオブジェクトの配列をラップする別の実験クラスTOrderItemsを定義します。
  5. クラスTOrderItemで4つのテストを実行します。これらはすべて期待どおりに機能します。
  6. クラスTOrderItemsに対してさらに10個のテストを実行します。これらのうち2つは失敗します(合計14回のテストのうち6回と8回が実施されました)。

これらの失敗したテストを説明するのに助けをいただければ幸いです。

これがソースコードで、その後私が得た出力は次のとおりです。

//-----------------------------------------------------------------------------------------------------------------
// Utility Funcions
//-----------------------------------------------------------------------------------------------------------------
let optionIntTo_s(aValue : option<int>) = 
    match aValue with
    | None    -> "null"
    | Some(_) -> sprintf "%d" (Option.get(aValue))


//-----------------------------------------------------------------------------------------------------------------
// Class TUnitTester
//-----------------------------------------------------------------------------------------------------------------
type TUnitTester = class
    //----------------------------------
    // Field Definitions
    //----------------------------------
    val mutable ftestCount : int
    val mutable fsuccessCount : int


    //----------------------------------
    // Constructors
    //----------------------------------
    new ()  =
        {ftestCount = 0;
         fsuccessCount = 0}


    //----------------------------------
    // Methods
    //----------------------------------
    member this.assertEqual(aTestValue, aExpectation, aDescription) = 
        this.ftestCount <- this.ftestCount + 1

        if (aTestValue = aExpectation) then
            this.fsuccessCount <- this.fsuccessCount + 1
            printfn "Test %d: assertEqual succeeded: expected %A: got %A; %s" this.ftestCount aExpectation aTestValue aDescription
        else
            printfn "Test %d: assertEqual failed:    expected %A: got %A; %s" this.ftestCount aExpectation aTestValue aDescription


    member this.assertFalse(aDescription, aTestValue : bool) = 
        this.ftestCount <- this.ftestCount + 1

        if (aTestValue) then
            this.fsuccessCount <- this.fsuccessCount + 1
            printfn "assertFalse succeeded: expected false: got false; %s" aDescription
        else
            printfn "assertFalse failed:    expected false: got true;  %s" aDescription


    member this.assertTrue(aDescription, aTestValue : bool) =
        this.ftestCount <- this.ftestCount + 1

        if (aTestValue) then
            this.fsuccessCount <- this.fsuccessCount + 1
            printfn "assertTrue  succeeded: expected true: got true;  %s" aDescription
        else
            printfn "assertTrue  failed:    expected true: got false; %s" aDescription


    member this.printStatistics() =
        printfn "total tests = %d; successes = %d; failures = %d"  this.ftestCount this.fsuccessCount (this.ftestCount - this.fsuccessCount)
end;;


//-----------------------------------------------------------------------------------------------------------------
// Class TOrderItem
//    Ref: "F# option cheat sheet" - http://missingfaktor.blogspot.com.au/2012/02/f-option-cheat-sheet.html
//-----------------------------------------------------------------------------------------------------------------
type TOrderItem = class
    //----------------------------------
    // Field Definitions
    //----------------------------------
    val mutable fquantity : option<int>


    //----------------------------------
    // Properties
    //----------------------------------
    member this.quantity  with get() = Option.get(this.fquantity) and 
                               set(aValue : int) = this.fquantity <- Some(aValue)

    member this.isNull    with get() = Option.isNone(this.fquantity)
    member this.isNotNull with get() = Option.isSome(this.fquantity)


    //----------------------------------
    // Constructors
    //----------------------------------
    new ()  =
        {fquantity = None;}

    new (aValue : int)  =
        {fquantity = Some(aValue);}


    //----------------------------------
    // Methods
    //----------------------------------
    member this.to_s() = optionIntTo_s(this.fquantity)
end;;



//-----------------------------------------------------------------------------------------------------------------
// Class TOrderItems
//-----------------------------------------------------------------------------------------------------------------
type TOrderItems = class
    //----------------------------------
    // Field Definitions
    //----------------------------------
    val fOrderItems : TOrderItem []


    //----------------------------------
    // Properties
    //----------------------------------
    member this.orderItems with get() = this.fOrderItems


    //----------------------------------
    // Constructors
    //----------------------------------
    new (aLength : int)  =
        { fOrderItems = Array.create aLength (TOrderItem())}


    //----------------------------------
    // Methods
    //----------------------------------
    member this.Item i = this.fOrderItems.[i]     //Translates to the operator this.[i]

    member this.setAll(aValue : int) = 
        for i = 0 to (Array.length this.fOrderItems) - 1 do
            this.fOrderItems.[i].quantity <- aValue

    member this.setFromCombination(aScale1, aScale2, (aOrderItems1 : TOrderItems), (aOrderItems2 : TOrderItems)) =
        for i = 0 to (Array.length this.fOrderItems) - 1 do
            this.fOrderItems.[i].quantity <- aScale1 * aOrderItems1.[i].quantity + aScale2 * aOrderItems2.[i].quantity

    member this.setFromDifference((aOrderItems1 : TOrderItems), (aOrderItems2 : TOrderItems)) =
        this.setFromCombination(1, -1, aOrderItems1, aOrderItems2)

    member this.setFromSum((aOrderItems1 : TOrderItems), (aOrderItems2 : TOrderItems)) =
        this.setFromCombination(1, 1, aOrderItems1, aOrderItems2)

    member this.setItem i (aValue : int) =         //TODO NUKE THIS METHOD LATER....
        this.fOrderItems.[i].quantity <- aValue

    member this.to_s() = 
        Array.fold (fun (accumulator : string) (item : TOrderItem) -> accumulator + item.to_s() + "; ") "" this.fOrderItems
        |> (fun (x) -> "[| " + x + "|]")
end;;


//-----------------------------------------------------------------------------------------------------------------
// Test Classes TOrderItem and TOrderItems
//    (A) Create unit tester instance.
//-----------------------------------------------------------------------------------------------------------------
let myTester = TUnitTester()


//-----------------------------------------------------------------------------------------------------------------
//    (B) Test Class TOrderItem
//-----------------------------------------------------------------------------------------------------------------
let myOrderItem = TOrderItem()
myTester.assertEqual(myOrderItem.to_s(), "null", "myOrderItem.to_s()")        //Test 1 - OK

myOrderItem.quantity <- 8000
myTester.assertEqual(myOrderItem.quantity, 8000, "myOrderItem.quantity")      //Test 2 - OK

myOrderItem.quantity <- 9000
myTester.assertEqual(myOrderItem.quantity, 9000, "myOrderItem.quantity")      //Test 3 - OK
myTester.assertEqual(myOrderItem.to_s(), "9000", "myOrderItem.to_s()")        //Test 4 - OK


//-----------------------------------------------------------------------------------------------------------------
//    (C) Test Class TOrderItems
//-----------------------------------------------------------------------------------------------------------------
let myOrderItems = TOrderItems(4)
myTester.assertEqual(myOrderItems.to_s(), "[| null; null; null; null; |]", "myOrderItems.to_s()")  //Test 5 - OK

myOrderItems.[2].quantity <- 1000
myTester.assertEqual(myOrderItems.to_s(), "[| null; null; 1000; null; |]", "myOrderItems.to_s()")  //Test 6 - Fails!

myOrderItems.setAll 5000
myTester.assertEqual(myOrderItems.[2].quantity, 5000, "myOrderItems.[2].quantity")                 //Test 7 - OK

myOrderItems.setItem 1 9999
myTester.assertEqual(myOrderItems.[0].quantity , 5000, "myOrderItems.[0].quantity")                //Test 8 - Fails!
myTester.assertEqual(myOrderItems.[1].quantity , 9999, "myOrderItems.[1].quantity")                //Test 9 - OK


let myOrderItems1 = TOrderItems(4)
let myOrderItems2 = TOrderItems(4)
let myOrderItems3 = TOrderItems(4)
let myOrderItems4 = TOrderItems(4)
let myOrderItems5 = TOrderItems(4)

myOrderItems1.setAll 5000
myOrderItems2.setAll 4000

myTester.assertEqual(myOrderItems1.to_s(), "[| 5000; 5000; 5000; 5000; |]", "myOrderItems1.to_s()")      //Test 10 - OK
myTester.assertEqual(myOrderItems2.to_s(), "[| 4000; 4000; 4000; 4000; |]", "myOrderItems2.to_s()")      //Test 11 - OK


myOrderItems3.setFromCombination(2, 3, myOrderItems1, myOrderItems2)
myTester.assertEqual(myOrderItems3.to_s(), "[| 22000; 22000; 22000; 22000; |]", "myOrderItems3.to_s()")  //Test 12 - OK


myOrderItems4.setFromSum(myOrderItems1, myOrderItems2)
myTester.assertEqual(myOrderItems4.to_s(), "[| 9000; 9000; 9000; 9000; |]", "myOrderItems4.to_s()")      //Test 13 - OK


myOrderItems5.setFromDifference(myOrderItems1, myOrderItems2)
myTester.assertEqual(myOrderItems5.to_s(), "[| 1000; 1000; 1000; 1000; |]", "myOrderItems5.to_s()")      //Test 14 - OK


//-----------------------------------------------------------------------------------------------------------------
//    (D) Report test statistics.
//-----------------------------------------------------------------------------------------------------------------
myTester.printStatistics()

そして最後に、MAC OS X上のmonoでMicrosoft(R)F#2.0コンパイラビルド2.0.0.0から取得した出力は次のとおりです。

Microsoft (R) F# 2.0 Compiler build 2.0.0.0
Copyright (c) Microsoft Corporation. All Rights Reserved.
Test 1: assertEqual succeeded: expected "null": got "null"; myOrderItem.to_s()
Test 2: assertEqual succeeded: expected 8000: got 8000; myOrderItem.quantity
Test 3: assertEqual succeeded: expected 9000: got 9000; myOrderItem.quantity
Test 4: assertEqual succeeded: expected "9000": got "9000"; myOrderItem.to_s()
Test 5: assertEqual succeeded: expected "[| null; null; null; null; |]": got "[| null; null; null; null; |]"; myOrderItems.to_s()
Test 6: assertEqual failed:    expected "[| null; null; 1000; null; |]": got "[| 1000; 1000; 1000; 1000; |]"; myOrderItems.to_s()
Test 7: assertEqual succeeded: expected 5000: got 5000; myOrderItems.[2].quantity
Test 8: assertEqual failed:    expected 5000: got 9999; myOrderItems.[0].quantity
Test 9: assertEqual succeeded: expected 9999: got 9999; myOrderItems.[1].quantity
Test 10: assertEqual succeeded: expected "[| 5000; 5000; 5000; 5000; |]": got "[| 5000; 5000; 5000; 5000; |]"; myOrderItems1.to_s()
Test 11: assertEqual succeeded: expected "[| 4000; 4000; 4000; 4000; |]": got "[| 4000; 4000; 4000; 4000; |]"; myOrderItems2.to_s()
Test 12: assertEqual succeeded: expected "[| 22000; 22000; 22000; 22000; |]": got "[| 22000; 22000; 22000; 22000; |]"; myOrderItems3.to_s()
Test 13: assertEqual succeeded: expected "[| 9000; 9000; 9000; 9000; |]": got "[| 9000; 9000; 9000; 9000; |]"; myOrderItems4.to_s()
Test 14: assertEqual succeeded: expected "[| 1000; 1000; 1000; 1000; |]": got "[| 1000; 1000; 1000; 1000; |]"; myOrderItems5.to_s()
total tests = 14; successes = 12; failures = 2
4

1 に答える 1

4

変化する

Array.create aLength (TOrderItem())

Array.init aLength (fun t -> TOrderItem())

最初のものは多くのコピーを持つ配列を作成します - それは本当に で使用するために設計されてintいます.2番目のものはあなたがしたいことをします

また、将来的には、投稿するコードを減らして質問を簡素化するのに役立ちます

于 2012-07-06T10:27:38.253 に答える