0

VS 2012 を使用した NUnit テストの下に、次のオブジェクト (Delphi からの簡略化されたポート) があります。

Public Class Class1
  Private fLoaded As Boolean
  Private fSample As String

  Private Sub LoadFromDB()
    If (fLoaded) Then
      Exit Sub
    End If

    fLoaded = True
    ' fDataModule.LoadFromDB(Me)
  End Sub

  Public Property SampleProp() As String
    Get
  LoadFromDB()
      Return fSample
    End Get
    Set(ByVal value As String)
      fSample = value
    End Set
  End Property

  Public Property Loaded() As Boolean
    Get
      Return fLoaded
    End Get
    Set(ByVal value As Boolean)
      fLoaded = value
    End Set
  End Property
End Class

オブジェクトは、そのプロパティがアクセスされたときにロード オン デマンドを実行すると想定されています。次の Nunit クラスはプロパティをテストしています。

Imports NUnit.Framework

<TestFixture> _
Public Class TestClass1

  <Test()> _
  Public Sub TestProperties()
    Dim TheClass As Class1

    TheClass = New Class1
    TheClass.Loaded = True

    TheClass.SampleProp = "Sample"
    TheClass.Loaded = False

    Assert.AreEqual("Sample", TheClass.SampleProp)

  End Sub

End Class

発生する問題は、Assert ステートメントにブレークポイントがあると、クラス プロパティ Loaded がデバッガーで True として表示され、内部変数を設定するコードが実行されていないことです。最終的に、オンデマンド ロードは実行されません。

物件の価値を変えるとは?Delphi では、DUnit を使用して、クラス プロパティが期待どおりに動作しました。

4

2 に答える 2

1

エイドリアンはこれについて正しいです。アサート行がフラグの設定をトリガーしています。この問題は面白そうだったので、それをコピーして、それが何をしているかを確認しました。私はいくつかの小さな変更を加えました:

Public Class Class1
    Private fLoaded As Boolean = False      ' vars in MY code are never nothing
    Private fSample As String = ""          '    without my say so

  ...

Private Sub LoadFromDB()
  If (fLoaded) Then
    Exit Sub
  End If

  fLoaded = True
  Debug.Print("Now, all your datas are belong to me.")
End Sub

そしてテストクラスでは:

Public Sub TestProperties()
  Dim TheClass As New Class1

    TheClass.Loaded = True
    TheClass.SampleProp = "Sample"
    TheClass.Loaded = False
    TheClass.SampleProp = "Not Sample"


    Debug.Assert(("Sample" = TheClass.SampleProp), "Msg")
End Sub

ほとんどの変更は無意味です。の出力行はLoadFromDB()、負荷が発火している場所からいつ発生するかを判断するためのものです。Assert ISが DataLoad を引き起こしています。Debug では、Assert 行にいて Load プロシージャにジャンプするのは自発的で気紛れに見えますが、それはあなたが書いた方法です。

GETTING は SETTING ではないため、prop はロードをトリガーTheClass.SampleProp = "Sample"し、Loaded フラグに関する限り何もしません。だから私が追加したアサートの直前に:

    If TheClass.SampleProp = "Not Sample" Then
        Debug.Print("Test did that")
    End If

データは Property Get の結果としてロードされますが、新しい行でもロード済みフラグが true に設定されているため、Assert はロードしません。書かれている方法に基づいて、すべてが正常に機能しているようです。

編集: 変数宣言を元に戻し、Sub New を追加しました:

    Private fLoaded As Boolean 
    Private fSample As String 

Public Sub New()
    Debug.Print("New == {0}", fLoaded)
End Sub

Newメンバー var を常に として報告しFalseます。ただし、デバッグでは、マウスオーバーでプロパティ値が として表示されTrueます。

奇妙なことに、Assert に到達するまでに、Loaded設定とリセットが完了しているため、それまでに正確であると期待するかもしれません。fLoadedAssert の Property Get ステートメントをトレースすると、最初は falseであることがわかります。直後に同じことが起こる

    Dim TheClass As New Class1

New が False を報告したにもかかわらず、マウス ポップアップには True が表示されます。

どちらのエラーも初期化することで解決されるため、初期化されていない var を処理する際fLoadedのマウスオーバー値表示でのエラーのように見えますLoaded

教訓は、可能な限り変数を初期化することです。

于 2013-09-19T23:26:55.720 に答える