Всегда ли для имитации объектов в C ++ требуются виртуальные методы или шаблоны?

Предположим, у меня есть классы

class Inner {
  public:
    void doSomething();
};

class Outer {
  public:
    Outer(Inner *inner);  // Dependency injection.

    void callInner();
};

. Правильное модульное тестирование говорит, что у меня должны быть тесты для Inner . Затем у меня должны быть тесты для Outer , которые используют не настоящий Inner , а скорее MockInner , чтобы я выполнял модульные тесты для функциональности, добавленной просто Внешний вместо полного стека Внешний / Внутренний .

Для этого Googletest , кажется, предлагает повернуть Внутренний в чистый абстрактный класс (интерфейс), например:

// Introduced merely for the sake of unit-testing.
struct InnerInterface {
  void doSomething() = 0;
};

// Used in production.
class Inner : public InnerInterface {
  public:
    /* override */ void doSomething();
};

// Used in unit-tests.
class MockInner : public InnerInterface {
  public:
    /* override */ void doSomething();
};

class Outer {
  public:
    Outer(Inner *inner);  // Dependency injection.

    void callInner();
};

Итак, в производственном коде я бы использовал Внешний (новый Внутренний) ; при тестировании Внешний (новый MockInner) .

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

Альтернативный подход - использовать шаблоны, как показано ниже:

class Inner {
  public:
    void doSomething();
};

class MockInner {
  public:
    void doSomething();
};

template
class Outer {
  public:
    Outer(I *inner);

    void callInner();
};

// In production, use
Outer obj;

// In test, use
Outer test_obj;

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

Эти два метода, виртуальные и шаблоны, являются только способы провести правильное модульное тестирование? Есть ли более эффективные способы проведения надлежащего модульного тестирования?

Под надлежащим модульным тестированием я подразумеваю , что каждый модульный тест проверяет только функции, представленные этим модулем, но не сам модуль » s также .

12
задан kirakun 24 March 2011 в 21:57
поделиться