Как получить доступ к частным полям класса от тестового использования UnitTest ++?

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

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

struct MyFixture : ClassUnderTest { };

TEST_FIXTURE(MyFixture, OneTest)
{
    do_something();
    CHECK(protected_field == true);
}

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

Я пытался объявить тестовые классы как друзья, но поскольку они создаются некоторым специальным способом UnitTest ++, мне не удалось сделать это все же.

У кого-либо есть какая-либо идея того, как завести тестовых друзей классов классы под тестом?

Есть ли другой способ приблизиться к этой проблеме более легким или другим способом?

Спасибо всем заранее.

13
задан davidag 18 January 2010 в 11:13
поделиться

5 ответов

Тестирование подразделения - это все о проверке ваших объектов через их общедоступный интерфейс. Тот факт, что это может быть трудно, поэтому писать , тестируемый код иногда упоминается как арт . Не каждый может сразу же написать тестичный код, поэтому люди изобрели XP приблизиться к тестам написания. Звучит нереально, работает в реальности.

Однако, если вы абсолютно необходимы для тестирования частных функций, вот список методов, которые я бы рассмотрел в порядке моих собственных предпочтений:

  1. Частные переменные участника доступны через государственные сетры и Геттерс

  2. Я бы порекомендовал сделать вас частным членом функцией нестатической функции не-члена в пространстве имен, который можно назвать E.g. Подробнее или Внутренний . Не объявляйте его в заголовочном файле, просто определите его в том же файле, где определены функции классных классов. Добавьте его декларацию в файл заголовка MyClass_internal.h в тестовом проекте устройства и проверьте его. Трудности вовлечены в значительной степени зависят от сложности вашей архитектуры.

  3. Сделайте свой тестовый класс наследует от вашего тестируемого класса. Это не связано с изменением вашего кода много, но может потребовать использования многократного наследства, которое в некоторых местах даже запрещено.

  4. Сделайте свой тест другу вашего тестируемого класса. Сложность зависит от того, что вы используете, которую вы используете. Скажем, с GTEST , которые я использую, это довольно сложно :)

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

6
ответ дан 1 December 2019 в 20:42
поделиться

Есть один действительно безобразный, но удивительно полезный взлом, который я обычно использую для тестирования подразделения:

#define private public
#define protected public

#include "class_to_be_tested.h"

// and here, all class's methods and fields are public :P

Не используйте его для чего-либо еще, чем тестирование единиц!

Кроме того, этот метод имеет некоторые ограничения - во-первых, не все частное префиксировано с частным . Во-вторых, один популярный компилятор покинул спецификатор доступа в символ линкера.

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

class my_class
{
private:
   char name[40];
   char grade;
   int age;
public:
   //
}

struct my_class_hack
{
public:
   char name[40];
   char grade;
   int age;

}

struct hack_it* my_class_hacked = (my_class_hack*)ptr;

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

14
ответ дан 1 December 2019 в 20:42
поделиться

Избегать, избегая тестирования частных вещей. Почему хочу проверить Private_field? Что становится ошибками, когда Private_field установлен на недопустимое значение? Можно ли проверить это неправильное поведение вместо того, чтобы утверждать на неправильном значении?

Другие варианты включают

  • PLAY с препроцессором, чтобы сделать его общественностью, когда код скомпилирован для тестирования подразделения

  • , извлечь личное поле и связанную с соответствующей логикой в ​​новый класс, где он будет публичным, и делает Classundertest На этом новом классе.

0
ответ дан 1 December 2019 в 20:42
поделиться

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

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

4
ответ дан 1 December 2019 в 20:42
поделиться

Я бы также выбрал #define Hack,

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

Я должен не согласиться с Дмитрием:

1.) Это добавило бы интерфейсы в мой производственный код только для тестирования и нарушило бы мою инкапсуляцию. Я не хочу, чтобы клиенты снова имели доступ к моим приватным данным

2.), как показано в 1.). -> хорошая идея, если эти интерфейсы действительно открыты только для тестирования

3.) работает только в том случае, если доступ защищен, что так или иначе нарушает инкапсуляцию

4.) также означает модификацию моего производственного кода только для тестирования и даже создает связь между производственным кодом и моим тестовым кодом!!!!

5.) С вашей точки зрения, это правильно, у меня скорее уродливый тестирующий код, чем уродливый код производства :)

.
4
ответ дан 1 December 2019 в 20:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: