2015-09-30 5 views
0

Я пытаюсь написать аддон, который позволит мне написать модульные тесты для VBA. У меня есть установка класса для тестирования утверждений и т. Д., Что мне не хватает, это способ укусить/издеваться над классами, есть ли способ сделать это?Написание VBA Unit Testing Suite

Для разъяснения я говорю о создании объектов, которые притворяются разными классами. Например, я хочу написать издеваться Адресной класса, Person класс будет работать с:

Person класса

Private Home as Address 

Sub ChangeAddress(NewStreetAddress as String) 
     Address.Street = NewStreetAddress 
end Sub 

Адрес Класс

Dim Street as String 
+0

На самом деле неясно, что вы просите, но это звучит, как вы могли бы искать [Интерфейсы и реализации] (http://www.cpearson.com/excel/Implements.aspx) –

+0

Вы должны видеть [это] (http://codereview.stackexchange.com/q/63004/23788) - обратите внимание, что этот код VBA/«модульная система тестирования» был в конечном итоге перенесен на C# в надстройку COM, которая превратилась в то, что в настоящее время известно как [** Rubberduck **] (http://www.rubberduck-vba.com). –

+0

Вам, вероятно, не нужно издеваться над классом «Адрес».То, что вам, вероятно, нужно, это способ указать экземпляр извне. Если вы 'New' в классе внутри' Person', вы делаете это неправильно. –

ответ

2

Testable, объектно-ориентированный VBA код, который позволяет вы контролируете зависимости, должны быть написаны против абстракций. Extensible logging Обзор кода Stack Exchange - хороший пример этого.

Вкратце, ваш код должен зависеть от интерфейсов - только тогда ваши модульные тесты пройдут в «поддельных» реализациях. Возьмите класс модуля ILogger из связанного CR пост:

Option Explicit 

Public Sub Log(ByVal output As String) 
End Sub 

Public Property Get Name() As String 
End Property 

Public Property Get MinLevel() As LogLevel 
End Property 

Это интерфейс. Одна реализация называется DebugLogger и идет как это - обратите внимание Реализует ILogger:

Option Explicit 

Private Type TDebugLogger 
    Name As String 
    MinLevel As LogLevel 
End Type 
Private this As TDebugLogger 

Implements ILogger 

Public Function Create(ByVal loggerName As String, ByVal loggerMinLevel As LogLevel) As ILogger 

    Dim result As New DebugLogger 
    result.Name = loggerName 
    result.MinLevel = loggerMinLevel 
    Set Create = result 

End Function 

Friend Property Get Name() As String 
    Name = this.Name 
End Property 

Friend Property Let Name(ByVal value As String) 
    this.Name = value 
End Property 

Friend Property Get MinLevel() As LogLevel 
    MinLevel = this.MinLevel 
End Property 

Friend Property Let MinLevel(ByVal value As LogLevel) 
    this.MinLevel = value 
End Property 

Private Sub ILogger_Log(ByVal output As String) 
    Debug.Print output 
End Sub 

Private Property Get ILogger_MinLevel() As LogLevel 
    ILogger_MinLevel = this.MinLevel 
End Property 

Private Property Get ILogger_Name() As String 
    ILogger_Name = this.Name 
End Property 

Теперь, если у вас есть код, который использует ILogger, тесты блок может пройти в реализации, что вместо печати вещи на консоль вызывает событие, которое сообщает, что сообщение регистрируется и на каком уровне: ваш тестовый модуль может обрабатывать эти события, устанавливать флаг уровня модуля и [при условии, что вы внедрили класс Assert или используете Rubberduck модульные тесты], вы можете позвонить Assert.IsTrue, чтобы подтвердить флаг. Или что угодно.

Подводя итог, он может быть полностью выполнен: у меня есть интерфейс IRepository с реализациями, попадающими в базу данных, а мои модульные тесты используют «поддельные» реализации, которые на самом деле просто обертывают Collection.

Что касается насмешливый, как, генерируя реализацию на лету и инъекционные, что ... это не то, что легко сделать, но я могу видеть Rubberduck предлагая нечто подобное в будущей версии ,


Отказ - я совладелец проекта Rubberduck и хранилище.