Создание тестируемого кода

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

Я хочу переопределить эти методы, чтобы исключить доступ к БД во время модульного тестирования.

Я подумал о следующих вариантах:

  1. Превратите файл в класс и переопределите методы.
    Основным минусом здесь является то, что это приводит к множеству изменений по всей кодовой базе.
    Не идеально, хотя это улучшает код...
  2. Оберните весь исходный файл #ifdef PRODUCTION_CODE и создайте новый исходный файл, содержащий заглушку, и оберните его противоположным, то есть сделайте все, что зависит от компиляции. Проблема здесь в том, что в системе сборки, которая выполняет регрессионные тесты, мне пришлось бы компилировать дважды, один раз, чтобы создавать приложения и делать регрессионные тесты, и дополнительное время для создания исполняемых файлов модульного теста.

Любые рекомендуемые способы сделать это?

4 ответа

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

Вот так:

 static DBAccessClass dac = new DBAccessClass ();

 void origFunction() { dac.origFunction(); }

И в тесте:

 dac = new DBAccessMockup();

Вы можете попробовать переопределить на уровне компоновщика. Имеют два разных файла.cpp, которые реализуют функции в заголовке, который описывает интерфейс БД - один вызывает реальную БД, а другой - фальшивый интерфейс. Когда вы ссылаетесь на модульное тестирование, замените одно на другое (могут помочь переменные, специфичные для целевых объектов в GNU make).

  1. Превратите файл в класс и переопределите методы. [...]
  2. Оберните весь исходный файл с помощью #ifdef [...]

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

Если вы идете с 2, рассмотрите возможность замены реализации функций. То есть внутри исходных функций задействуйте код тестирования (основанный на if).

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

Вы также можете посмотреть книгу Майкла Фезерса " Эффективная работа с устаревшим кодом". Он не только обсуждает именно эти типы проблем, но и включает в себя множество примеров на C++ (в дополнение к Java, C и C#). Перья также является первоначальным создателем CppUnit.

Другие вопросы по тегам