Экстремальное программирование. Разработка через тестирование | страница 47



В данном случае код теста длиннее, чем сам тестируемый код. Код точно такой же, как код в классе Money (кажется, я уже предвижу необходимость создания абстрактного класса):


Sum

public Expression plus(Expression addend) {

return new Sum(this, addend);

}

$5 + 1 °CHF = $10, если курс обмена 2:1

$5 + $5 = $10

Операция $5 + $5 возвращает объект Money

Bank.reduce(Money)

Приведение объекта Money с одновременной конверсией валют

Reduce(Bank,String)

Sum.plus

Expression.times


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


$5 + 1 °CHF = $10, если курс обмена 2:1

$5 + $5 = $10

Операция $5 + $5 возвращает объект Money

Bank.reduce(Money)

Приведение объекта Money с одновременной конверсией валют

Reduce(Bank,String)

Sum.plus

Expression.times


Если мы получили работающий метод Sum.times(), значит, объявление Expression.times() не составит для нас труда. Вот соответствующий тест:


public void testSumTimes() {

Expression fiveBucks = Money.dollar(5);

Expression tenFrancs = Money.franc(10);

Bank bank = new Bank();

bank.addRate("CHF", "USD", 2);

Expression sum = new Sum(fiveBucks, tenFrancs). times(2);

Money result = bank.reduce(sum, "USD");

assertEquals(Money.dollar(20), result);

}


И снова тест получился длиннее тестируемого кода. (Те, кто достаточно много работал с JUnit, должно быть уже догадались, как решить эту проблему. Остальным я рекомендую прочитать раздел «Fixture (Фикстура)» в главе 29, посвященной шаблонам xUnit.)


Sum

Expression times(int multiplier) {

return new Sum(augend.times(multiplier), addend.times(multiplier));

}


В предыдущей главе мы изменили тип переменных augend и addend на Expression, поэтому теперь, чтобы скомпилировать код, нам необходимо добавить в интерфейс Expression метод times():


Expression

Expression times(int multiplier);


При этом нам следует изменить режим видимости методов Money.times() и Sum.times() (они должны стать общедоступными):