Главная » C# » Верификация в приложении обмена валют в Visual C# (Sharp)

0

Для выполнения тестового класса TestcurrencyTrader применяется следующий код: TestCurrencyTrader els = new TestCurrencyTrader();  els.IntializeExchangeRate() ;

В модифицированном тестовом коде создается экземпляр класса Testcur- rencyTester, после чего вызывается метод InitializeExchangeRate(). Но являея ли данный код тестом? Ведь метод InitializeExchangeRate () не возвращает значение и не имеет выходного параметра. Такой тест можно сравнить с отправлием письма по почте. Хотя, скорее всего, письмо дойдет до адресата, полной увенности в этом нет. Использование тестов, об успешном завершении которых можно судить только с определенной вероятностью, является очень плохой идеей.

Нам  необходимо  переместить  верификационный  код  из  процедуры  тестирования в класс TestCurrencyTrader следующим образом:

class TestCurrencyTrader : CurrencyTrader { public void InitializeExchangeRate() {

ExchangeRate = 100.0;

if (ExchangeRate ! = 100.0) {

throw new Exception("100.0 verification failed");

}

}

}

Код для верификации, что переменной ExchangeRate было присвоено то же самое значение, которое было возвращено, выделен жирным шрифтом.

ПРИМЕЧАНИЕ

Применяемые нами тесты становятся все более сложными, и вы можете задаться вросом:  "Зачем  делать  это  таким  образом?" Для  целей данной  книги  мы  пишем тесты и создаем нашу собственную инфраструктуру тестирования. Обычно мы бы этого не сделали, а воспользовались бы для создания тестов готовой инфраструктурой тестирания, например NUnit (http://www.nunit.org), или инструментами, входящими в состав Microsoft Visual Studio Professional. Но здесь  я  хочу  продемонстрировать,  как  использать  не  инструмент тестирования,  а  язык  С#.  В  процессе  изучения  написания  тестов с самого начала вы поймете, что можно ожидать от инфраструктур тестирования.

Использование условных операторов

Размещение верификационного кода в классе является приемлемым в контексте тестового класса TestCurrencyTrader. Но все еще остается проблема тестируемти классов, которые не предоставляют свое состояние.

Чтобы понять эту проблему, давайте возвратимся к коду для предварительного погрева духовки. Представьте себе, что мы переписали класс oven, включив в него верификационный тест, следующим образом:

class Oven {

private int _temperature;

public void SetTemperature(int temperature) {

_temperature = temperature;

if (_tenperature != 100.0) {

throw new Exception("100.0 verification failed");

}

}

public bool AreYouPreHeated() {

// Проверяем, соответствует ли температура требуемой, return false;

}

}

Жирным  шрифтом  выделен  код,  в большой  мере, для такой же  верификации,  как и верификация в классе CurrencyTrader, которая проверяет параметр temperature на соответствие определенному значению. В то время как данная проверка полезна для конкретного теста, в большом плане она бесполезна. В его теперешнем виде тестовый код допускает единственное действительное значение параметра temperature— юо.о ; любое другое значении сгенерирует исключение. Такое рение явно не является приемлемым.

Данную проблему можно решить с помощью условных операторов. Условные опаторы — это специальные ключевые слова, с помощью которых разработчик может определить, скомпилировался ли определенный фрагмент исходного кода. Далее приводится пример исходного кода, содержащего условные операторы:

class TestCurrencyTrader : CurrencyTrader { public void InitializeExchangeRate() {

ExchangeRate = 100.0;

#if XNTEGRA.TE TESTS

if (ExchangeRate != 100.0) {

throw new Exception("100.0 verification failed");

}

#endif

}

}

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

между операторами #if и #endif, компилируется при соблюдении определенного условия. Операторы этого типа  называются  директивами  препроцессора (preprocessor directive). В данном примере условием компиляции кода, заключенно в блок #if/#endi£, является значение true идентификатора INTEGRATE_TESTS.

Компиляционные идентификаторы, как INTEGRATE_TESTS, можно определить в иодном коде или в используемой вами интегрированной среде разработки. В Visual С# Express идентификатор INTEGRATE_TESTS можно определить следующим образом:

1. Щелкните  правой  кнопкой  мыши  название  проекта  и  выберите  пункт  меню

Properties.

2. Откройте вкладку Build.

3.   Введит е  INTEGRATE_TESTS В текстово е  пол е  Conditional  Compilation Symbols.

Верификация с использованием частичных классов

Условная компиляция приходится кстати, когда, в зависимости от конфигурации, нужно включить или исключить код. Но некоторые программисты недолюбливают включать условно компилируемый код в функции, т. к. такой код очень трудно сровождать. Другим решением будет применить ключевое слово partial class совместно с операторами условной компиляции.

До сих пор во всех примерах при определении класса все его методы и другие элемеы объявлялись в одном месте — между фигурными скобками кода класса. С помощью частичных классов разные элементы класса можно объявлять в разных местах. При компиляции отдельные фрагменты класса будут собраны в одно  целое определение класса. Для нашего тестового кода мы можем создать частичный класс для реализации теста и условно компилируемую тестовую реализацию частичного класса. Далее при-

водится   модифицированны й  код  класс а  TestCurrencyTrader, которы й  МОЖН О ИСПОЛЬ-

зовать для тестирования состояния без предоставления его внешнему коду:

partial class TestCurrencyTrader : CurrencyTrader { public void InitializeExchangeRate() {

ExchangeRate = 100.0;

}

}

#if !XNTEGRATE„TESTS

partial class TestCurrencyTrader : CurrencyTrader { public void VerifyExchangeRate(double value)  {

if (ExchangeRate != value) {

throw new Exception("ExchangeRate verification failed");

}

}

}

#endif

В данном объявлении класса ключевому слову class предшествует ключевое слово partial. Первая реализация класса Testcurrencyrrader демонстрирует пример, когда состояние не предоставляется внешнему коду. Вторая реализация класса TestcurrencyTrader, которая объявлена в контексте блока условной компиляции, содержит метод verifyExchangeRate (). Этот верификационный метод тестирует свойство ExchangeRate на наличие определенного значения.

ПРИМЕЧАНИЕ

Частичные классы можно применять только в контексте одной сборки. В данном коексте сборка означает скомпилированные фрагменты исходного кода .NET, рассмоенные в главе 1. Иными словами, если вы определите частичный класс в библиотеке класса, тогда все фрагменты данного частичного класса нужно определить в этой же библиотеке  класса.

С помощью частичных  классов можно с легкостью разбить функциональность на отдельные  файлы  исходного  кода;  таким  образом,  модификация, исходного  кода в одном  файле не затронет исходный код в другом файле. В данном примере донстрируется использование частичных классов для манипулирования внутренним состоянием класса без нарушения при этом правила, запрещающего предоставлие внутреннего состояния. Частичные классы также применяются в генераторах кода, где один файл исходного кода содержит специальный код, а другой содержит генератор кода.

Источник: Гросс  К. С# 2008:  Пер. с англ. — СПб.:  БХВ-Петербург, 2009. — 576 е.:  ил. — (Самоучитель)

По теме:

  • Комментарии