Unexplainable code behavior with Unit test

匆匆过客 提交于 2019-12-11 19:34:30

问题


I have the following object (simplified port from Delphi) under a NUnit test using VS 2012.

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

The object is suppose to perform a Load-on-Demand when it's properties are accessed. The following Nunit class is testing the property.

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

The problem that occurs is that with a breakpoint on the Assert Statement, the class property Loaded shows as True in the debugger, without any of my code having been executed that would set the internal variable. The end result is that my on-demand load will not get executed.

What is changing the value of the property? In Delphi, using DUnit, the class properties behaved as expected.


回答1:


Adrian is correct on this, the Assert line is triggering the flag to set. This issue looked interesting, so I copied it to see what it is doing. I made a few small changes:

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

And in Test class:

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

Most of the changes are meaningless. The print line in LoadFromDB() is meant to determine WHEN from WHERE the load is firing. The Assert IS causing the DataLoad. In Debug it LOOKS spontaneous and freaky to be on the Assert line and jump to to Load procedure but that is how you have it written.

Since GETTING not SETTING a prop triggers the load, TheClass.SampleProp = "Sample" does nothing as far as the Loaded flag is concerned. So just before the Assert I added:

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

The data does load as a result of the Property Get, AND the Assert no longer does because my new line also sets the loaded flag to true. It is all seems to be working as it should based on how it is written.

EDIT: I reverted the variable declarations and added a Sub New:

    Private fLoaded As Boolean 
    Private fSample As String 

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

New Always reports the member var as False. However in Debug, the mouseover does show the Property value as True.

Oddly, by time you get to the Assert, Loaded has been set and reset so by then you might expect it to be accurate. If you trace into the Property Get statement in the Assert, you'll see that fLoaded is initially false. The same thing happens right after

    Dim TheClass As New Class1

The mouse pop up displays True even though New just reported False.

Since both errors are resolved by initializing fLoaded it looks to be an error in the mouseover value display of Loaded when dealing with uninitialized vars.

The lesson is, initialize variables whenever possible.




回答2:


I had cases where object-preview of the debugger was triggering the getter and therefore the preload of my object.



来源:https://stackoverflow.com/questions/18902042/unexplainable-code-behavior-with-unit-test

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!