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

发生的问题是,在断言语句上有一个断点,类属性 Loaded 在调试器中显示为 True,而我的任何代码都没有被执行来设置内部变量。最终结果是我的按需加载将无法执行。

是什么改变了房产的价值?在 Delphi 中,使用 DUnit,类属性的行为符合预期。

4

2 回答 2

1

Adrian 在这一点上是正确的, Assert 行正在触发设置标志。这个问题看起来很有趣,所以我复制它来看看它在做什么。我做了一些小改动:

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()用于确定负载从何处触发的时间。断言导致数据加载。在 Debug 中,在 Assert 行并跳转到 Load 过程看起来很自发和怪异,但这就是您编写它的方式。

由于 GETTING not SETTING 会触发加载,TheClass.SampleProp = "Sample"因此就 Loaded 标志而言,什么也不做。所以就在我添加的断言之前:

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

由于 Property Get 确实加载了数据,并且 Assert 不再加载,因为我的新行也将加载的标志设置为 true。根据它的编写方式,这一切似乎都在正常工作。

编辑:我恢复了变量声明并添加了一个 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它已经被设置和重置,所以到那时你可能期望它是准确的。如果您追踪到 Assert 中的 Property Get 语句,您会发现它fLoaded最初是错误的。同样的事情发生在之后

    Dim TheClass As New Class1

即使 New 刚刚报告 False,鼠标弹出窗口也会显示 True。

由于这两个错误都是通过初始化解决的,因此在处理未初始化的变量时, fLoaded它看起来是鼠标悬停值显示中的错误。Loaded

教训是,尽可能初始化变量。

于 2013-09-19T23:26:55.720 回答
0

我遇到过调试器的对象预览触发 getter 并因此预加载我的对象的情况。

于 2013-09-21T15:34:40.467 回答