Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2009.12.06;
Скачать: [xml.tar.bz2];

Вниз

Как тестировать не публичные методы?   Найти похожие ветки 

 
Kolan ©   (2009-10-06 16:12) [0]

Здравствуйте!

Как правильно поступать, если нужно написать юнит-тесты на не публичные методы?

Делать их публичными не хочется, а без этого тесты, понятно, не компиляться.


 
Игорь Шевченко ©   (2009-10-06 16:15) [1]

Тестировать публичные. Разве не очевидно ?


 
DVM ©   (2009-10-06 16:17) [2]


> юнит-тесты на не публичные методы?

Если метод не публичный, значит он все равно где то рано или поздно должен использоваться в публичном методе, иначе смысла в нем нет. Поэтому тестировать надо публичные.


 
Kolan ©   (2009-10-06 16:19) [3]

Публичный метод включает в себя вызовы (иногда вложенные) нескольких не публичных методов. Если я напишу тест только на публичный метод, то это будет что-то вроде «ваша программа не работает», так как узнать что именно отвалилось будет трудно.


 
Игорь Шевченко ©   (2009-10-06 16:22) [4]

Значит надо пересматривать архитектуру класса.

Вообще-то для тестов предусматривается поиск ошибок с отладчиком в руках, если тест проваливается. Странно, что приходится озвучивать тривиальные вещи.


 
Kolan ©   (2009-10-06 16:50) [5]

Точно узнать нужный метод полезнее, так быстрее будет. Я бы предпочел, чтобы тесты могли игнорировать области видимости, как, например, это работает с интерфейсами.


 
DVM ©   (2009-10-06 16:52) [6]


> Kolan ©   (06.10.09 16:50) [5]

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


 
Игорь Шевченко ©   (2009-10-06 17:40) [7]

Kolan ©   (06.10.09 16:50) [5]

В древнем Китае желающим странного просто отрубали голову. Очень мудро и действенно.

Если доступ извне к непубличным частям классов не предусмотрен, зачем пытаться его изобрести, пусть даже для тестирования ? Очевидно, надо пересмотреть свои классы и сделать так, чтобы они смогли быть протестированы без извращений.


 
Суслик_   (2009-10-06 18:52) [8]

Игорь не в духе...

А вообще поддерживаю.


 
pasha_golub ©   (2009-10-06 19:20) [9]

объяви протекдет и пользуйся хакерством :)

THackClass = class(TTestedClass);

THackClass(TestedObj).RunProtected


 
Alkid ©   (2009-10-06 19:24) [10]

А я поддерживаю оратора. Тестирование непубличных компонент - вполне осмысленный шаг как только их сложность превышает некий порог.


 
pasha_golub ©   (2009-10-06 19:25) [11]

Юнит тест моджно прописать в том же модуле где и непубличные члены. Тогда доступ будет в пределах модуля.


 
Канадец   (2009-10-06 19:58) [12]

> Kolan ©   (06.10.09 16:50) [5]
>
> Точно узнать нужный метод...


А exception handling and logging на что?

Unit тестирование private методов это бесполезная трата времани. Можно и переменный потестировать, если очень хочется. Это никому не интересно.

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


 
Kolan ©   (2009-10-07 10:38) [13]

Случай, когда, по моему мнению, тестировать внутренние методы нужно, а переделывать класс плохо.

У меня есть класс, который занимается математикой. Внешний интерфейс состоит из одного метода, который принимает массивчик и возвращает массивчик. А внутри, для расчета результирующего массива вызывается добрый десяток методов.

Зачем мне выставлять внутренние методы на показ? — Не зачем.

Если я буду тестировать только интерфейсный методы, то тест либо будет жутко сложным (варианты должны быть такие, чтобы проверить работу внутренних методов) либо будет тестировать весьма поверхностно.

Это про про отрубание головы.

Помещать тест в модуль не хочется, на то они и тесты, чтобы быть отдельно. Кроме того Делфи так мило все по папочкам сам раскладывает.

А вот как применить хак я не понял.

Сделал так:

THackTCustomCalibration = class(TCustomCalibration);

TestTCustomCalibration = class(TTestCase)
 strict private
   FCustomCalibration: TCustomCalibration;
 public
   procedure SetUp; override;
   procedure TearDown; override;
 published
   procedure TestTruncateWinFunction;
 end;

...

procedure TestTCustomCalibration.TestTruncateWinFunction;
var
 WinFuction: TDoubleArray;
begin
 SetLength(WinFuction, 31);
 THackTCustomCalibration(FCustomCalibration).TruncateWinFunction(WinFuction);< /B>
 Assert(Length(WinFuction) = 16);

 SetLength(WinFuction, 71);
 FCustomCalibration.TruncateWinFunction(WinFuction);
 Assert(Length(WinFuction) = 36);
end;

Все равно ругается, что не может получить доступ.


 
Игорь Шевченко ©   (2009-10-07 10:41) [14]


> У меня есть класс, который занимается математикой. Внешний
> интерфейс состоит из одного метода, который принимает массивчик
> и возвращает массивчик. А внутри, для расчета результирующего
> массива вызывается добрый десяток методов.


А что Фаулер говорит насчет таких классов ?


 
Kolan ©   (2009-10-07 10:48) [15]

Не знаю. Не вижу запах. Куда смотреть.


 
KSergey ©   (2009-10-07 10:48) [16]

Сделать методы не приватными, а протектными и честно пронаследоваться в тестах?
формально, понятно, это ухудшение интерфейса, типа немного поднимаем область видимости привата, но критично ли это в конкретной задаче?


 
Kolan ©   (2009-10-07 10:52) [17]

Так они и есть протекид. А как наследоваться правильно оболочка теста должна быть потомком TTestCase же.


 
KSergey ©   (2009-10-07 10:53) [18]

я не знаю как у вас устроено, но можно унутысь этой оболочки запихнуть поле - наследника тестируемого класса.


 
KSergey ©   (2009-10-07 10:54) [19]

унутысь => унутырь


 
Anatoly Podgoretsky ©   (2009-10-07 10:57) [20]

> KSergey  (07.10.2009 10:54:19)  [19]

Не легче, что такое унутырь


 
Skyle ©   (2009-10-07 11:07) [21]


> Anatoly Podgoretsky ©   (07.10.09 10:57) [20]
> > KSergey  (07.10.2009 10:54:19)  [19]
>
> Не легче, что такое унутырь

Это место, где у ней неонка, но сибирский диалект.


 
Kolan ©   (2009-10-07 11:42) [22]

KSergey, но стремно же пихать код для тестирования в класс.


 
KSergey ©   (2009-10-07 11:50) [23]

Кому чинить канализацию стрёмно - пусть найдет работу по душе.


 
Игорь Шевченко ©   (2009-10-07 11:51) [24]

Kolan ©   (07.10.09 11:42) [22]

И все-таки, голову рубить надо.

"Как и для класс с кучей атрибутов, обычное решение для класса с чрезмерным объемом кода состоит в том, чтобы применить "Выделение класса" (Extract Class, 161) или "Выделение подкласса" (Extract Subclass, 330). Полезно установить, как клиенты использу.т класс, и применить "Выделение интерфейса (Exctract Interface, 341) для каждого из этих вариантов. В результате может выясниться, как расчленить класс еще далее".

Фаулер, "Рефакторинг", с. 89


 
Kolan ©   (2009-10-07 11:57) [25]

То есть речь идет о запахе Large class, если я правильно понял. Я не вижу в своем классе этот запах. Мне не кажется что он делает слишком много. Если бы, например, мне методы из этого класса понадобились еще где-то, то у меня была бы причина его расчленять.

Или это не тот запах?


 
Игорь Шевченко ©   (2009-10-07 12:00) [26]


> Мне не кажется что он делает слишком много


Если у тебя есть класс, у которого наружу торчит один метод, который внутри себя вызывает кучу методов, которые ты не можешь протестировать, то это неправильный класс с точки зрения Фаулера. Далее тебе решать, то ли соблюсти невинность и переделать класс по теории, то ли плюнуть на теорию и оставить, как есть, но при этом извращаться для тестирования.


 
Kolan ©   (2009-10-07 12:32) [27]

Согласился.
Наверно, если бы я использовал TDD еще при написании класса, так само собой бы и получилось.


 
Канадец   (2009-10-07 16:05) [28]

Кстати ничего зазорного в том, что есть класс у которого торчит один публичный метод нет. Это называется Facade. Но Facade подразумевает целую архитектуру за собой, а не кучу private методов.


 
Kolan ©   (2009-10-07 16:43) [29]


> Но Facade подразумевает целую архитектуру за собой, а не
> кучу private методов.

Верно, поэтому ваш комментарий про фасад выглядит странно. Казалось бы: причем тут фасад?


 
Канадец   (2009-10-07 18:01) [30]


>меня есть класс, который занимается математикой. Внешний
> интерфейс состоит из одного метода


Из чего я делаю вывод, что потребителям данной ф-сти собственно и нужен один метод.

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

Как по твоему всё это называется? и как это организовано сейчас?

Ответы на эти вопросы подставь в мой пост Канадец   (07.10.09 16:05) [28]



Страницы: 1 вся ветка

Форум: "Прочее";
Текущий архив: 2009.12.06;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.53 MB
Время: 0.005 c
15-1255017902
TUser
2009-10-08 20:05
2009.12.06
Сакральный смысл понятия дурак :)


4-1224815622
Skazi21101
2008-10-24 06:33
2009.12.06
Вопрос по RS-232C


6-1210247266
laao
2008-05-08 15:47
2009.12.06
как корректно завершать работу с поднятым IdHTTPServer ?


6-1180454227
AlexanderMS
2007-05-29 19:57
2009.12.06
Работа с локальной сетью.


4-1223554921
МистерТ
2008-10-09 16:22
2009.12.06
COM-порт изменение скорости при синхронном режиме работы





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский