Подтвердить что ты не робот

Интерфейсы против шаблонов для инъекций зависимостей в С++

Чтобы иметь возможность unit test моего кода на С++, я обычно передаю конструктор класса под одним или несколькими объектами, которые могут быть либо "производственным кодом", либо фальшивыми/макетными объектами (позвольте назвать эти объекты инъекции). Я сделал это либо

  • Создание интерфейса, который наследует класс "производственный код" и класс fake/mock.
  • Выполнение класса под классом шаблона, который принимает типы объектов инъекции в качестве параметров шаблона, и экземпляры объектов инъекции в качестве параметров для конструктора.

Некоторые случайные мысли:

  • До тех пор, пока у нас нет понятий (С++ 0x), только документация и именование параметров подскажут, что обеспечить тестируемый класс (при использовании шаблонов).
  • Не всегда возможно создавать интерфейсы для устаревшего кода
  • Интерфейс в основном создан только для того, чтобы иметь возможность делать инъекции зависимостей
  • Точно так же: шаблонный тест класса выполняется только для включения инъекции зависимостей

Каковы ваши мысли? Существуют ли другие решения этой проблемы?

4b9b3361

Ответ 1

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

Ответ 2

С С++ существует еще один вариант - вы даете своим макетным классам те же имена, что и реальные классы, и при связывании своих модульных тестов просто связывайте их с файлами mock object/library вместо реальных.

Ответ 3

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

Я думаю, что для этой цели интерфейсы лучше (пока у нас не будет понятий в С++ 0x TR1)... если только вы не можете замедлить некоторые "узкие места". Интерфейсы более динамичны и могут переключаться во время выполнения.

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

Ответ 4

Не знаю, помогает ли это, но вы можете иметь конструкторы шаблонов:

struct Class_Under_Test
{
    template <typename Injected>
    Class_Under_Test()
    {
         ...

    // and even specialize them
    template <>
    Class_Under_Test <A_Specific_Injection_Class>
    {
        ...

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