2013-09-19 3 views
0

У меня есть следующий объект (упрощенный порт из Delphi) при испытании NUnit с помощью 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 проверяет свойство.

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 показывает, как Истинные в отладчике, без какой-либо из моего кода того, были выполнены, что бы установить внутреннюю переменную. Конечным результатом является то, что моя загрузка по запросу не будет выполнена.

Что меняет стоимость недвижимости? В Delphi, используя DUnit, свойства класса вели себя как и ожидалось.

+1

Может быть, потому что для проверки значения 'SampleProp' утверждение должно вызывать его значение, которое, в свою очередь, запускает' LoadFromDB() ', которое устанавливает' Loaded' в 'True'? Почему вы вручную устанавливаете «Loaded» на «True» в модульном тесте? – Adrian

+0

Большая проблема в том, что Assert еще не выполнен! Я останавливаюсь в отладчике в строке Assert, и свойство Loaded считывает True. Когда Assert действительно запрашивает свойство, загрузка по требованию исключается из-за состояния флага. Мой большой вопрос: кто меняет состояние моей внутренней, частной переменной класса? – user2426159

+0

Ваша личная переменная не так уж и закрыта, поскольку вы можете (и) менять ее извне. Я должен сказать, что мне показалось, что я видел, о чем вы говорите, в первый раз, когда я его запустил, - но ТОЛЬКО в первый раз, когда я начинал делать изменения ниже. Посмотрел странно, но я не смог воспроизвести его после изменений. – Plutonix

ответ

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 

А в классе Test:

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() предназначена для определения КОГДА, ГДЕ, когда нагнетается заряд. Утверждение IS, вызывающее DataLoad. В Debug он СМОТРЕТЬ спонтанным и причудливым, чтобы быть на линии Assert и перейти к Load Load, но именно так вы его и написали.

Поскольку ПОЛУЧЕНИЕ НЕ УСТАНАВЛИВАЕТСЯ, спусковой крючок запускает нагрузку, TheClass.SampleProp = "Sample" ничего не делает с флагом Loaded. Так что перед Assert я добавил:

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

Данные делает нагрузку в результате Property Get, и Утверждайте больше не делает, потому что моя новая линия также устанавливает загруженный флаг верно. Кажется, что все работает так, как должно быть, исходя из того, как оно написано.

EDIT: Я вернула объявления переменных и добавил Sub New:

Private fLoaded As Boolean 
    Private fSample As String 

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

New Всегда сообщает вар член как False. Однако в Debug наведение мыши показывает значение свойства как True.

Как ни странно, по времени вы попадаете на Assert, Loaded был установлен и сброшен, поэтому к тому времени вы можете ожидать, что он будет точным. Если вы проследите в инструкции Property Get в Assert, вы увидите, что fLoaded изначально ложно. То же самое происходит сразу после

Dim TheClass As New Class1 

Дисплей мыши отображается True, даже если новый только что сообщил False.

Поскольку обе ошибки разрешены путем инициализации fLoaded, это выглядит как ошибка при отображении значения наведения мыши Loaded при работе с неинициализированными vars.

Урок - инициализировать переменные, когда это возможно.

+0

Вы правильно относитесь к GET перед тем, как SET запускает флаг fLoaded для переключения, и я был знаком с этим. Однако меня смущает то, что при установке точки останова на тестовой строке Assert мой объектный код выполняется вне моего контроля. Установка точки останова на строке Assert, оператор Debug print показывает, что мой внутренний код уже выполнен во время остановки отладчика. В то время даже точки останова в моем объектном коде не наблюдаются. Я проверил, что мой код работает правильно, поэтому мне просто нужно жить и помнить это странное поведение. – user2426159

+0

См. Редактирование, которое я сделал - я не видел никакого «нежелательного выполнения кода» - оператор Assert установил 'floaded', и он должен. Он смотрит, как точки останова игнорируются, когда указатель мыши сообщает True, когда вы знаете, что это False. Это не означает, что код должен выполняться вне вашего контроля - в этом случае это означает, что отчет по указанию мыши неверен. Что еще более важно, когда переменные инициализируются, все работает одинаково, а индикаторы отладки верны. (Я не знаю, какой 'Debug print statement показывает ...' вы имеете в виду - моя версия сейчас замусорена. – Plutonix

0

У меня были случаи, когда объектный предварительный просмотр отладчика запускал геттер и, следовательно, предварительную загрузку моего объекта.

Смежные вопросы