Модульное тестирование конструктора класса

В C ++, как можно проверить конструктор класса? Например:

Class myClass{
int a;

public:
myClass(); //Constructor
void reset(); //resets a to 0;

};

//Constructor defined to initialize a to 0
myClass::myClass(){
reset();
}

//reset sets a to 0
void myClass::reset(){
a = 0;
}

Как бы я протестировал конструктор myClass ()? Я не могу получить доступ к частному члену данных, поэтому будет ли правильно сказать, что если сброс работает, то работает конструктор?

3

Решение

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

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

  • Извлечь сложный кусок кода что вы хотите проверить во втором классе. Затем вы можете протестировать второй класс через его открытый интерфейс. Эта опция привлекательна, когда извлечение второго класса улучшает код, даже если не учитывать тестируемость.

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

  • Стратегическое отступление. Тестирование кода изолированно, при прочих равных условиях хорошо, но нет закона о том, что все код должен быть проверенным в изоляции. Иногда правильный ответ — просто позволить тестировать этот код как побочный эффект тестирования чего-то другого. В конце концов, все остальные ваши тесты для этого класса будут вызывать конструктор, поэтому, если что-то не так с конструктором, это, вероятно, вызовет сбой одного из этих других тестов. Возможно, будет сложнее охватить все пути таким образом, и в то время, когда вы получите этот сбой, будет больше проблем отследить причину сбоя, потому что теперь вы не знаете, является ли проблема конструктором или другой проверяемой вещью. , Это может иметь или не иметь большого значения. Действительно ли стоит потрудиться тестировать этот код изолированно, принимая во внимание, что еще вы могли бы использовать в это время и вероятность того, что этот тест когда-нибудь действительно обнаружит ошибку? Будет ли обзор кода более полезным способом провести это время? Есть ли что-то еще, что было бы более полезно сделать?

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

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

  • Поддерживать отдельный интерфейс для использования тестами. Иметь набор методов, которые дают доступ, который вам нужен, и чье имя имеет префикс, такой как «testOnly». Так что в вашем случае это будет testOnlyGetA (). Вам нужно будет дисциплинировать вызов этих методов только из тестов, и теперь вам нужно поддерживать интерфейс большего размера, чем раньше.

  • Держи свой нос и делать #define private public в вашем тестовом файле, прежде чем включать заголовок, который вы хотите проверить.

6

Другие решения

Upd. Извините, неправильно понял.

Вы можете добавить функцию тестирования друга в класс или функцию тестирования члена класса (которая лучше тестирует детали реализации, но иногда невозможна из-за ограничений инфраструктуры тестирования)

0

Вы можете добавить тестовый пример повышения класса:

Class myClass{
private:
int a;

public:
myClass(); //Constructor
void reset(); //resets a to 0;
void test_a_reset() {
BOOST_CHECK_EQUAL(a, 0);
}

};

Хотя я не уверен в том, как вы проводите тестирование. Это может быть не то, что вы хотите.

0

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

void testMyClassConstructor()
{
class myClassPublic
{
public:
int a;
myClassPublic();
void reset();
};

typedef union
{
myClass* original;
myClassPublic* testView;
} u_myClass;

myClass testInstance;
u_myClass testUnion;
testUnion.original = &testInstance;

assert(testUnion.testView->a == 0);
}

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

-1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector