Сделать приватный метод общедоступным для модульного тестирования ... хорошая идея? - PullRequest
279 голосов
/ 16 августа 2011

Примечание модератора: Здесь уже опубликовано 39 ответов (некоторые из них были удалены). Перед тем как опубликовать ваш ответ, подумайте, стоит ли илиВы не можете добавить что-то значимое к обсуждению.Скорее всего, вы просто повторяете то, что уже сказал кто-то еще.


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

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

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

ОБНОВЛЕНИЕ

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

Однако я могу видеть, что все указывают на то, что этого никогда не должно происходить.И, думая об этом немного больше, я думаю, что изменение вашего кода для размещения тестов - плохая идея - в конце концов, я полагаю, что тестирование - это своего рода инструмент поддержки, а изменение системы на «поддержку инструмента поддержки», если хотите, является явным явлением.плохая практика.

Ответы [ 33 ]

9 голосов
/ 16 августа 2011

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

9 голосов
/ 16 августа 2011

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

У вас есть несколько вариантов, если вы хотите их протестировать.

  • Использовать отражение
  • Предоставить доступ к пакету методов

В качестве альтернативы вы можете создать новый класс с помощью вспомогательного метода в качестве открытого метода, если он является достаточно хорошим кандидатом для нового класса.

Здесь очень хорошая хорошая статья .

6 голосов
/ 27 июля 2015

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

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

6 голосов
/ 16 августа 2011

Если вы используете C #, вы можете сделать метод внутренним.Таким образом, вы не загрязняете общедоступный API.

Затем добавьте атрибут в dll

[assembly: InternalsVisibleTo ("MyTestAssembly")]

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

6 голосов
/ 27 июля 2015

с точки зрения модульного тестирования, вам определенно не следует добавлять больше методов;Я полагаю, что вам лучше создать тестовый пример только для вашего first() метода, который будет вызываться перед каждым тестом;затем вы можете несколько раз позвонить - next(), previous() и last(), чтобы узнать, соответствуют ли результаты вашим ожиданиям.Я полагаю, что если вы не добавите больше методов в свой класс (только для целей тестирования), вы будете придерживаться принципа «черного ящика» тестирования

5 голосов
/ 16 августа 2011

В своем обновлении вы говорите, что хорошо просто протестировать с помощью общедоступного API.Здесь фактически есть две школы.

  1. Тестирование черного ящика

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

  2. тестирование белого ящика.

    Школа белого ящика считает, что естественно использовать знания о реализации класса, а затем протестировать класс, чтобы узнать, что он работает какэто должно быть.

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

5 голосов
/ 16 августа 2011

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

Кроме того, объявляя метод общедоступным, что означает, что через шесть месяцев (после того, как вы забыли, что единственная причина сделать метод общедоступным - это тестирование), вы (или если вы передали проект) кому-то совсем другой человек не будет его использовать, что приведет к непредвиденным последствиям и / или кошмару обслуживания.

5 голосов
/ 16 августа 2011

Сначала посмотрите, должен ли метод быть извлечен в другой класс и обнародован.Если это не так, сделайте его защищенным и добавьте в Java аннотацию с @VisibleForTesting.

4 голосов
/ 17 августа 2011

Частные методы, которые вы хотите тестировать изолированно, указывают на то, что в вашем классе есть еще одна «концепция».Извлеките эту «концепцию» в свой собственный класс и протестируйте ее как отдельный «блок».

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

4 голосов
/ 16 августа 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...