Public int получитьЧислоПосещений()
{ return 0; } } Листинг 16.5 показывает начальный шаг. Мы написали новую тестовую функцию тестСоздатьЛакомку. Эта функция создает объект класса Лакомка и затем убеждается, что хранимое количество посещений равно 0. Конечно, реализация метода получитьЧислоПосещений неверна, но она обеспечивает прохождение теста. Это позволит нам в будущем выполнить рефакторинг (для улучшения решения). Введем в класс Лакомку объект-контейнер, хранящий данные о разных посещениях (как элементы списка в массиве изменяемого размера). Для его создания используем класс-контейнер Array List из библиотеки Java 2. В будущем нам потребуются три метода контейнера: add (добавить элемент в контейнер), get (получить элемент из контейнера), size (вернуть количество элементов в контейнере). Листинг 16.6. ЛАKOMKА.java import java.util.ArrayList; public class Лакомка { private ArrayList егоПосещения = new ArrayList(); // создание объекта егоПосещения - контейнера посещений public int получитьЧислоПосещений () { return егоПосещения.size(); // возврат количества элементов в контейнере // оно равно количеству посещений кафе } } Отметим, что после каждого изменения мы прогоняем все тесты, а не только функцию тестСоздатьЛакомку. Это дает гарантию, что изменения не испортили уже работающий код. На следующем шаге следует определить, как к Лакомке добавляется посещение кафе. Так будет выглядеть простейший тестовый вариант: Листинг 16.7. TecтЛакомки.java public void тестДобавитьПосещение() { double булочки = 7.0; // 7 булочек double стоимость = 12.5 * 7; // цена 1 булочки = 12.5 руб. double вес = 60.0; // взвешивание лакомки double дельта = 0.0001; // точность Лакомка g = new Лакомка(); g.добавитьПосещениеКафе(булочки, стоимость, вес); assertEquals(1, g.получитьЧислоПосещений());
} В этом тесте объект класса ПосещениеКафе не создается. Очевидно, что создавать объект и добавлять его в список должен метод добавитьПосещениеКафе объекта Лакомка. Листинг 16.8. Лакомка.jауа Public void добавитьПосещениеКафе((double булочки, double стоимость, double вес) { ПосещениеКафе v = new ПосещениеКафе(new Date(), булочки, стоимость, вес); егоПосещения.add(v); // добавление эл-та v в контейнер посещений } Опять прогоняются все тесты. Анализ программного кода в функциях тестДобавитьПосещение и тестСоздатьПосещениеКафе показывает, что он частично дублируется. Обе функции создают одинаковые локальные переменные и инициализируют их одинаковыми значениями. Чтобы избавиться от дублирования, проведем рефакторинг тестируемой программы и сделаем локальные переменные свойствами класса. Листинг 16.9. ТестЛакомки.jауа import junit.framework.*; import ПосещениеКафе; import java.util.Date; public class ТестЛакомки extends TestCase { private double булочки - 7.0; // 7 булочек private double стоимость = 12.5 * 7; // цена 1 булочки = 12.5 p. private double вес = 60.0; // взвешивание лакомки private double дельта = 0.0001; // точность public ТестЛакомки(String name) { super(name); } public void тестСоздатьПосещениеКафе() { Date дата = new Date(); ПосещениеКафе v = new ПосещениеКафе(дата. булочки. стоимость, вес); assertEquals(date, v.получитьДату()); assertEquals(12.5 * 7. v.получитьСтоимость(). дельта); assertEquals(7.0. v.получитьБулочки(). дельта); assertEquals(60.0. v.получитьВес(), дельта); assertEquals(12.5. v.получитьЦену(). дельта): } public void тестСоздатьЛакомку() { Лакомка g = new Лакомка (); assertEquals(0. g.получитьЧислоПосещений()); } public void тестДобааитьПосещение() { Лакомка g = new Лакомка(); g.добавитьПосещениеКафе(булочки. стоимость, вес); assertEquals(1. g.получитьЧислоПосещениРК)); } } Еще раз подчеркнем: наличие тестов позволяет определить, что этот рефакторинг ничего не разрушил в программе. Мы будем убеждаться в этом преимуществе постоянно, после очередного применения рефакторинга для реструктуризации программы. Каждый раз после внесения в код изменений запускаются тесты и проверяется работоспособность программы.
Очередная задача — после добавления к Лакомке объектов ПосещениеКафе у Лакомки можно запрашивать генерацию отчетов. Сначала напишем тесты, начнем с простейшего теста. Листинг 16.10. TecтЛакомки.java public void тестОтчетаОдногоПосещения() { Лакоика g = new Лакоика(); g.добавитьПосещениеКафе(булочки. стоимость, вес); Отчет r = g.создатьОтчет(); assertEquals(0. r.получитьИзменениеВеса(), дельта); assertEqualз(булочки, г.получитьПотреблениеБулочек(), дельта); assertEquals(0, r.получитьВесНаБулочку(), дельта); assertEquals(стоимость. r.получитьСтоимостьБулочек(), дельта); } При создании этого тестового варианта мы обдумали детали генерации отчета. Во-первых, Лакомка должна обладать методом создатьОтчет. Во-вторых, этот метод должен возвращать объект класса с именем Отчет. В-третьих, Отчет должен иметь несколько методов-селекторов. Значения, возвращаемые методами-селекторами, следует проанализировать. Для вычисления изменения веса (или приращения веса на одну булочку) одного посещения кафе недостаточно. Чтобы вычислить эти значения, необходимы, как минимум, два посещения, С другой стороны, одного визита достаточно, чтобы сосчитать потребление и стоимость булочек. Разумеется, тестовый вариант не компилируется. Поэтому необходимо добавить соответствующие методы и классы. Сначала добавим код, обеспечивающий компиляцию, но не обеспечивающий выполнение тестов. Листинг 16.11. Лакомка.java, TecтЛакомки.java и Отчет.jаvа Лакомка.java public Отчет создатьОтчет() { return new Отчет(); } ТестЛакомки.java public void тестОтчетаОдногоПосещения() { Лакомка g = new Лакомка(); g.добавитьПосещениеКафе(булочки, стоимость, вес); Отчет r = g.создатьОтчет(); assertEquals(0, r.получитьИзменениеВеса(), дельта); assertEquals(булочки. r.получитьПотреблениеБулочек(), дельта); assertEquals(0. r.получитьВесНаБулочку(), дельта); assertEquals(cтоимость,. r.получитьСтоимостьБулочек(),. дельта); } Отчет.java Public class Отчет { Public double получитьИзменениеВеса() {return егоИзменениеВеса;} Public double получитьВесНаБулочку() {return егоВесНаБулочку;} Public double получитьСтоииостьБулочек() {return егоСтоимостьБулочек;}
Public double получитьЛотреблениеБулочек() {return егоПотреблениеБулочек;} private double егоИзменениеВеса; private double егоВесНаБулочку; private double егоСтоимостьБулочек; private double егоПотреблениеБулочек; } Код в листинге 16.11 компилируется и запускается, но его недостаточно для того, чтобы прошли тесты. Нужен рефакторинг кода. Для начала сделаем минимально возможные изменения. Листинг 16.12. Лакомка.java и Отчет.java Лакомка.java public Отчет создатьОтчет() { Отчет r = new Отчет(); ПосещениеКафе v = (ПосещениеКафе) егоПосещения. Get(0); // занести в v первый элемент из контейнера посещений r.устВесНаБулочку(0); r.устИзменениеВеса(0); r.устСтоимостьБулочек(v.получитьСтоимость()); r.устПотреблениеБулочек(v.получитьБулочки()): return r; } Отчет.java
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|