问题描述
我在使用 VS 2012 的 NUnit 测试下有以下对象(来自 Delphi 的简化端口).
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
假设对象在其属性被访问时执行按需加载.以下 Nunit 类正在测试该属性.
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
出现的问题是,在 Assert 语句上有一个断点时,类属性 Loaded 在调试器中显示为 True,而没有执行任何设置内部变量的代码.最终结果是我的按需加载将无法执行.
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.
什么改变了财产的价值?在 Delphi 中,使用 DUnit,类属性的行为符合预期.
What is changing the value of the property? In Delp using DUnit, the class properties behaved as expected.
推荐答案
Adrian 在这点上是正确的,Assert 行正在触发标志设置.这个问题看起来很有趣,所以我复制了它来看看它在做什么.我做了一些小改动:
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
在测试类中:
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()
中的打印行旨在确定何时从何处触发负载.导致 DataLoad 的 Assert IS.在 Debug 中,在 Assert 行并跳转到 Load 过程看起来是自发和怪异的,但这就是你编写的方式.
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.
由于 GETTING not SETTING a prop 会触发加载,TheClass.SampleProp = "Sample"
就加载标志而言不做任何事情.所以就在我添加的 Assert 之前:
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
由于 Property Get 数据确实加载,并且 Assert 不再加载,因为我的新行也将加载的标志设置为 true.根据它的编写方式,这一切似乎都在正常工作.
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.
我恢复了变量声明并添加了一个 Sub New:
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
总是将成员 var 报告为 False
.但是在调试中,鼠标悬停确实将属性值显示为 True
.
New
Always reports the member var as False
. However in Debug, the mouseover does show the Property value as True
.
奇怪的是,当您使用 Assert 时,Loaded
已设置并重置,因此您可能会期望它是准确的.如果您跟踪到 Assert 中的 Property Get 语句,您将看到 fLoaded
最初为 false.同样的事情发生在
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
即使 New 刚刚报告 False,鼠标弹出也显示 True.
The mouse pop up displays True even though New just reported False.
因为这两个错误都是通过初始化 fLoaded
解决的,所以在处理未初始化的变量时,Loaded
的鼠标悬停值显示看起来是一个错误.
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.
这篇关于单元测试无法解释的代码行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!