单元测试无法解释的代码行为 [英] Unexplainable code behavior with Unit test

查看:96
本文介绍了单元测试无法解释的代码行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用 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.

这篇关于单元测试无法解释的代码行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆