Как вы выполняете модульное тестирование кода, который взаимодействует со сторонними COM-объектами и создает их экземпляры?

StackOverflow https://stackoverflow.com/questions/70482

Вопрос

Одна из самых больших проблем, которая в настоящее время удерживает меня от полного погружения в модульное тестирование, заключается в том, что действительно большой процент пишущего мной кода сильно зависит от сторонних COM-объектов из разных источников, которые также имеют тенденцию взаимодействовать друг с другом (я Я пишу надстройки для Microsoft Office, используя несколько вспомогательных библиотек, если вам нужно знать).

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

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

Я был бы особенно благодарен за примеры или инструменты для Delphi, но был бы также рад более общим советам и объяснениям более высокого уровня.

Спасибо,

Оливер

Это было полезно?

Решение

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

Поскольку у вас есть части вашего кода, непосредственно создающие экземпляры COM-объектов, это не совсем подходит.Если вы можете изменить этот код, вы можете использовать фабричный шаблон:они используют фабрику для создания COM-объекта.Вы можете издеваться над фабрикой, чтобы возвращать альтернативные объекты.

Доступ к объекту осуществляется через оболочку или через исходный COM-интерфейс, зависит от вас.Если вы решите имитировать COM-интерфейс, не забудьте добавить в макет IUnknown::QueryInterface, чтобы вы знали, что вы имитировали все интерфейсы, особенно если объект затем передается какому-либо другому COM-объекту.

Альтернативно, ознакомьтесь с CoTreateAsClass метод.Я никогда не использовал его, но он может сделать то, что вам нужно.

Другие советы

Все сводится к «проектированию с учетом тестируемости».В идеале вам не следует создавать экземпляры этих COM-объектов напрямую, а следует обращаться к ним через уровень косвенности, который можно заменить фиктивным объектом.

Теперь сам COM обеспечивает определенный уровень косвенности, и вы могли бы предоставить макет объекта, который заменил бы настоящий, но я подозреваю, что его создание будет трудным, и я сомневаюсь, что вы получите большую помощь от существующей структуры макетирования. .

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

Статья в Википедии содержит хорошее введение в тему.Википедия

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top