Модульное тестирование частных методов [дубликат]
этот вопрос уже есть ответ здесь:
- Как проверить частную функцию или класс, который имеет частные методы, поля или внутренние классы? 45 ответов
Я в процессе написания модульных тестов. В частности, я хочу проверить некоторые частные методы.
до сих пор я придумать с помощью.
#define private public
но я не доволен этим, так как это уничтожит всю инкапсуляцию с точки зрения модульного теста.
какие методы вы используете для модульного тестирования частных методов.
8 ответов:
Если методы достаточно сложны, чтобы гарантировать тестирование в изоляции, то рефакторинг их в свой собственный класс(Ы) и тестирование через их публичный интерфейс(ы). Затем используйте их в частном порядке в исходном классе.
а не противно
#define
hack вы упоминаете в вопросе, более чистый механизм, чтобы сделать тест другом тестируемого класса. Это позволяет тестовому коду (и только тестовому коду) получить доступ к частным лицам, защищая их от всего остального.однако предпочтительнее тестировать через открытый интерфейс. Если ваш класс X имеет много кода в частных функциях-членах, то, возможно, стоит извлечь новый класс Y, который используется реализация класса X. Этот новый класс Y затем может быть протестирован через его открытый интерфейс, не подвергая его использованию клиентам класса X.
Если вы используете Google Test, вы можете использовать FRIEND_TEST легко объявить ваше приспособление теста как друг к классу под тестом.
и вы знаете, если бы тестирование частных функций было однозначно плохим, как говорили некоторые другие ответы, то, вероятно, он не был бы встроен в Google Test.
вы можете узнать больше о том, когда тестирование частных функций хорошо или плохо в ответ.
сделайте тестовый класс другом исходного класса. Это объявление друга будет внутри
#define UNIT_TEST
флаг.class To_test_class { #ifdef UNIT_TEST friend test_class; #endif }
теперь для вашего модульного теста вы будете компилировать код с флагом
-DUNIT_TEST
. Таким образом, вы сможете проверить частную функцию.теперь ваш модульный тестовый код не будет вставлен в производственную среду, как
UNIT_TEST
флаг будет false. Следовательно, код по-прежнему безопасен.Также вам не понадобится специальная библиотека для модульное тестирование.
Я знаю, что это более старый вопрос, но кажется, что никто не поделился относительно хорошим методом, который я предпочитаю, поэтому вот он:
изменить метод, который вы хотите проверить от
private
toprotected
. Для других классов метод по-прежнему будетprivate
, но теперь вы можете получить "тестовый" класс из вашего базового класса, который предоставляет частную функциональность, которую вы хотите протестировать.вот минимальный пример:
class BASE_CLASS { protected: int your_method(int a, int b); }; class TEST_CLASS : public BASE_CLASS { public: int your_method(int a, int b) { return BASE_CLASS::your_method(a, b); } }
конечно, вам придется обновите модульные тесты для выполнения тестов на производном классе вместо базового класса, но после этого любое изменение, внесенное в базовый класс, будет автоматически отражено в классе "тестирование".
определить хак-это ужасная идея. Произвольно переписывать свой код с препроцессором, когда вы идете на компиляцию, никогда не разумно.
теперь, как уже упоминали несколько человек, спорно, следует ли вообще тестировать частные методы. Но это не распространяется на случай, когда вы намеренно скрыли конструкторы, чтобы ограничить instantiaton определенными областями или несколькими другими более эзотерическими случаями.
кроме того, вы не можете дружить с пространством имен и "дружба" не наследуется в C++, поэтому в зависимости от вашей платформы модульного тестирования, вы могли бы быть в беде. К счастью, если вы используете подталкивания.Тест, там в элегантном решении этого вопроса в виде светильников.
http://www.boost.org/doc/libs/1_52_0/libs/test/doc/html/utf/user-guide/fixture/per-test-case.html
вы можете дружить с прибором и создавать все экземпляры, которые вы используете в своих функциях модульного тестирования, объявляя их как статический к приспособлению и с объемом модуля. Если вы используете пространство имен, не волнуйтесь, вы можете просто объявить свое устройство в пространстве имен и свои тестовые случаи за пределами пространства имен, а затем использовать оператор разрешения области для доступа к статическим членам.
на
BOOST_FIXTURE_TEST_CASE
макрос позаботится о создании экземпляра и сносе вашего приспособления для вас.
после многих часов это то, что я решил быть лучшим решением для тех, кто желает проверить свои личные функции. Это комбинация ответов от Макс DeLiso и Милош.
если вы используете boost:: unit-test то есть простое и элегантное решение.
использовать
protected
вместоprivate
в ваши классы/* MyClass.hpp */ class MyClass { protected: int test() { return 1; } };
создать приспособление:
/* TestMyClass.cpp */ class F : public MyClass {}; BOOST_FIXTURE_TEST_SUITE(SomeTests, F) // use any protected methods inside your tests BOOST_AUTO_TEST_CASE(init_test) { BOOST_CHECK_EQUAL( test(), 1 ); } BOOST_AUTO_TEST_SUITE_END()
таким образом, вы можете свободно использовать любые из
MyClass
функции без#define private public
или добавлять друзья вам класс!
Я не думаю, что модульные тесты потребуются для частных методов.
Если метод является частным, он может использоваться только внутри этого класса. Если вы протестировали все публичные методы, используя этот частный метод, то нет необходимости тестировать это отдельно, так как он использовался только этими многими способами.