Тестирование белого ящика - друзья или препроцессор? - PullRequest
4 голосов
/ 08 октября 2010

Представьте, что у нас есть такой класс:

class Testee
{
public:
   void Func()
private:
   void auxFunc()
};

, и мы хотим провести модульное тестирование белого ящика на нем.Как вы думаете, какой подход лучше?Объявить класс тестера другом класса тестируемого?Или используйте препроцессор так:

  class Testee
    {
    public:
       void Func()
#ifndef UNITTEST_SYMBOL
    private:
#elif
    public:
#endif
       void auxFunc()
    };

и позже в файле тестирования

#define UNITTEST_SYMBOL
#include "Testee.h"
#undef UNITTEST_SYMBOL

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

Ответы [ 4 ]

4 голосов
/ 08 октября 2010

Как насчет:

#ifndef UNITTEST_SYMBOL
#define semiprivate private 
#else
#define semiprivate public
#endif

и объявить свой класс как:

  class Testee
    {
    public:
       void Func()
    semiprivate:
       void auxFunc()
    };

или даже, если вы достаточно смелы, при тестировании выполните #define private public.

2 голосов
/ 08 октября 2010

В файле модульного теста. Вы можете попробовать

#define private public
#include "Testee.h"

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

У меня есть все остальные мои заголовочные файлы до # define

1 голос
/ 03 февраля 2019

Ниже приведен способ, которым люди следуют для тестирования белого ящика,

#define private friend cTestDriver; private
#define protected friend cTestDriver; protected
//included all your class header from which you like to access
//the private/protected method
#include Testee.h"
#undef private
#undef protected

Класс cTestDriver будет иметь оболочки / сеттеры / геттеры для доступа ко всем закрытым и защищенным членам.

Кроме того, вы должны понимать порядок файлов заголовков.

Например:

File1.h

#include "Testee.h"
--
--
--

файл TestDriver.h

#include File1.h
#define private friend cTestDriver; private
#define protected friend cTestDriver; protected
//included all your class header from which you like to access
//the private/protected method
#include Testee.h"
#undef private
#undef protected

В указанном выше случае Testee.h будет открыт, пока мы открываем File1.h. Так что макросы здесь не будут эффективными.

Примечание: вы можете получить предупреждение о множественном объявлении друга.

1 голос
/ 08 октября 2010

Используя метод friend, объявление будет зависеть от имени тестового класса, поэтому, если вы когда-нибудь измените его имя, объявление также должно быть изменено. Более того, я использую Unittest ++, поэтому реальное имя тестового набора формируется макросом.

Метод с определением меньше хлопот тогда. Кроме того, я бы просто поместил определение как глобальную опцию компилятора вместо того, как вы показываете, например

gcc -DUNIT_TESTING_ON

#ifdef UNIT_TESTING_ON
  public: //or protected maybe
#else
  private:
#endif

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

...