よくかんでたべること

そのままのみこまずに、ね。

VB Lite Unitを試してみる(2)

前回ダウンロードしたサンプルのReadme.meをがんばって読んでみましたが、とにかくサンプルのソースを読んでみましょうってことなので、サンプルを見ながらFizzBuzzを書いてみることにしました。

まずFizzBuzz関数を。

Option Compare Database
Option Explicit

Private Const NUMBER_FIZZ = 3
Private Const NUMBER_BUZZ = 5
Private Const NUMBER_FIZZBUZZ = 15

Function ConvertFizzBuzz(number As Integer) As String

    '0以下の場合
    If CInt(number) <= 0 Then
        MsgBox "入力文字列が0以下です"
        Exit Function
    End If

    '15の倍数ならば"FizzBuzz"
    If number Mod NUMBER_FIZZBUZZ = 0 Then
        ConvertFizzBuzz = "FizzBuzz"
    '3の倍数ならば"Fizz"
    ElseIf number Mod NUMBER_FIZZ = 0 Then
        ConvertFizzBuzz = "Fizz"
    '3の倍数ならば"Buzz"
    ElseIf number Mod NUMBER_BUZZ = 0 Then
        ConvertFizzBuzz = "Buzz"
    Else
        ConvertFizzBuzz = CStr(number)
    End If

End Function

clsFizzBuzz.cls

次にテストクラスです。

Option Compare Database
Option Explicit

Implements ITestCase

Private Function ITestCase_TestCaseInstance() As ITestCase
    Dim objResult As New tclsTestFizzBuzz '!!ここにテストクラス名を書く!!
    Debug.Assert TypeName(objResult) = TypeName(Me)
    Set ITestCase_TestCaseInstance = objResult
End Function

Private Property Get ITestCase_Suite() As Variant
    ' Do nothing here
    ' Only run tests within RunTest.
End Property

Private Sub ITestCase_RunTest( _
    ByVal TestNum As Long, _
    TestName As String, _
    ExpectErrNum As Long, _
    EndOfTests As Boolean _
)
    Dim obj As New clsFizzBuzz
    Dim objTestNum As New TestNumGenerator
    Dim input_num As Integer
    Dim answer_str As String

    Select Case TestNum
    '3のテスト
    Case objTestNum.NextNumber
        input_num = 3
        TestName = CStr(input_num) & " equals Fizz"
        answer_str = "Fizz"
        AssertEqual obj.ConvertFizzBuzz(input_num), answer_str, "Not the right answer"
    '5のテスト
    Case objTestNum.NextNumber
        input_num = 5
        TestName = CStr(input_num) & " equals Buzz"
        answer_str = "Buzz"
        AssertEqual obj.ConvertFizzBuzz(input_num), answer_str, "Not the right answer"
    '15のテスト        
    Case objTestNum.NextNumber
        input_num = 15
        TestName = CStr(input_num) & " equals FizzBuzz"
        answer_str = "FizzBuzz"
        AssertEqual obj.ConvertFizzBuzz(input_num), answer_str, "Not the right answer"
    '16のテスト 
    Case objTestNum.NextNumber
        input_num = 16
        TestName = CStr(input_num) & " not equal (Fizz and Buzz)"
        answer_str = CStr(input_num)
        AssertEqual obj.ConvertFizzBuzz(input_num), answer_str, "Not the right answer"

    Case Else
        EndOfTests = True

    End Select
    
End Sub

tclsTestFizzBuzz.cls

テストの書きかた(?) ※ツッコミお願いします!

1)ITestCaseを継承

Implements ITestCase

2)継承した関数ITestCase_TestCaseInstanceとプロパティITestCase_Suiteはそのままコピペして使い回す ※テストクラス名だけは変更すること

Private Function ITestCase_TestCaseInstance() As ITestCase
    Dim objResult As New tclsTestFizzBuzz '!!ここにテストクラス名を書く!!
    Debug.Assert TypeName(objResult) = TypeName(Me)
    Set ITestCase_TestCaseInstance = objResult
End Function

Private Property Get ITestCase_Suite() As Variant
    ' Do nothing here
    ' Only run tests within RunTest.
End Property

3)サブルーチンITestCase_RunTestにテストを書いてみる

Private Sub ITestCase_RunTest( _
    ByVal TestNum As Long, _
    TestName As String, _
    ExpectErrNum As Long, _
    EndOfTests As Boolean _
)

ここも決まりっぽい。
次に試したい関数とTestNumGeneratorを呼び出す。

    Dim obj As New clsFizzBuzz
    Dim objTestNum As New TestNumGenerator

TestNumGenerator、ちょっと独特ですね。
このあとテストケースはSelect Caseに羅列します。分岐の条件部分にCase objTestNum.NextNumberと書くのです。
TestNumGeneratorがないと、次のSelect Case文の条件をすべて通ってくれないようです。
というのは、VBAのSelect Caseは他の言語のようにbreakやexitなしで分岐から出てしまうからなのでしょうか・・・。
テストはSelect Caseではじまり、

 Select Case TestNum

テストケースはCase objTestNum.NextNumberから書いてAssertEqualで判定する

    Case objTestNum.NextNumber
        input_num = 15
        TestName = CStr(input_num) & " equals FizzBuzz"
        answer_str = "FizzBuzz"
        AssertEqual obj.ConvertFizzBuzz(input_num), answer_str, "Not the right answer"

AssertEqualはもともと備わっている関数でした。

AssertEqual (比較元), (比較先), [省略可:失敗したときのメッセージ]

おわりはこれで締める。

    Case Else
        EndOfTests = True
    End Select

他に気づいたこと

テストクラスのクラスファイル名は、
サンプルのようにtclsで始まる必要はないようです。
Testという文字列が必須でもないようです。

あと、実行コマンド名のRunTests、sをつけ忘れてしばらくハマったことも白状します。

以上です。もっとサンプルをあさりたいのですが、とりあえずこちらで打ち止めにします。