Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


Public class ПосещениеКафе




{

}

Этот код компилируется, тест проходит, и мы готовы добавить необходимую функциональность.

Листинг 16.4. ТестЛакомки.jауа и ПосещениеКафе.jауа

ТестЛакомки.java

import junit.framework.*;

import ПосещениеКафе;

Import java.util.Date

public class ТестЛакомки extends TestCase

{

public TecтЛакомки(String name)

{

super(name):

}

public void тестСоздатьПосещениеКафе()

{

Date дата = new Date();

double булочки = 7.0; // 7 булочек

double стоимость = 12.5 * 7;

// цена 1 булочки - 12.5 руб.

double вес = 60.0; // взвешивание лакомки

double дельта = 0.0001; // точность

ПосещениеКафе v =

new ПосещениеКафе(дата, булочки, стоимость, вес);

assertEquals (дата, v.получитьДату());

assertEquals (12.5 * 7, v.получитьСтоииость(), дельта);

assertEquals (7.0, v.получитьБулочки(), дельта);

assertEquals (60.0, v.получитьВес(), дельта);

assertEquals (12.5, v.получитьЦену(). дельта);

}

}

ПосещениеКафе.java

import Java.uti1.Date;

public class ПосещениеКафе

{

private Date егоДата;

private double егоБулочки;

private double егоСтоимость;

private double eroBec;

public ПосещениеКафе (Date дата, double булочки,

double стоимость, double вес)

{

егоДата = дата;

егоБулочки = булочки;

егоСтоимость = стоимость;

егоВес = вес;

}

public Date получитьДату() { return егоДата;}

public double получитьБулочки() { return егоБулочки;}

public double получитьСтоимость() { return егоСтоимость;}

public double получитьЦену(){ return егоСтоимость/егоБулочки;}

public double получитьВес () {return eroBec;}

}

На этом шаге мы добавили тесты в класс ТестЛакомки, а также добавили методы в класс ПосещениеКафе. Унаследованные методы assertEquals позволяют проводить сравнение ожидаемых и фактических результатов тестирования.

Очевидно, вы удивитесь этому подходу. Неужели нельзя вначале написать весь код класса ПосещениеКафе, а потом создать тесты? Ответ достаточно прост. Написание тестов перед написанием программного кода дает важное преимущество: мы знаем, что весь ранее созданный код компилируется и выполняется. Следовательно, любая ошибка вызывается текущими изменениями, а не более ранним кодом. И значимость этого преимущества усиливается по мере продвижения вперед.

Далее определимся с хранением объектов класса ПосещениеКафе. Очевидно, что свойство егоВес характеризует лакомку. Таким образом, объект ПосещениеКафе записывает часть состояния лакомки па момент посещения кафе. Следовательно, нужно создать объект Лакомка и содержать объекты класса ПосещениеКафе в нем.

Листинг 16.5. ТестЛакомки.java и Лакомка.java

ТестЛакомки.java

import junit.framework.*;

import ПосещениеКафе;

import java.util.Date

public class ТестЛакомки extends TestCase

{

public TecтЛакомки(String name)

{

super(name);

}

public void тестСоздатьЛакомку ()

{

Лакомка g = new Лакомка ();

assertEquals(0, д. получитьЧислоПосещений ());

}

}

Лакомка.Java

Public class Лакомка

{

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);





Поделиться с друзьями:


Дата добавления: 2018-10-18; Мы поможем в написании ваших работ!; просмотров: 201 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Неосмысленная жизнь не стоит того, чтобы жить. © Сократ
==> читать все изречения...

2332 - | 2040 -


© 2015-2025 lektsii.org - Контакты - Последнее добавление

Ген: 0.011 с.