Comment testez-vous le code d'unité qui interagit avec et instancie des objets COM tiers?

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

Question

L’un des plus gros problèmes qui me empêche actuellement de plonger à fond dans les tests unitaires est qu’un pourcentage très important du code que j’écris dépend fortement d’objets COM tiers provenant de sources différentes qui tendent également à interagir les uns avec les autres. (J'écris des compléments pour Microsoft Office en utilisant plusieurs bibliothèques auxiliaires si vous avez besoin de le savoir).

Je sais que je devrais probablement utiliser des objets fictifs, mais comment pourrais-je m'y prendre exactement dans ce cas? Je peux voir que c'est relativement facile quand je dois simplement passer une référence à un objet déjà existant mais que certaines de mes routines instancient elles-mêmes des objets COM externes et les transmettent parfois à un autre objet COM externe d'une bibliothèque différente. / p>

Quelle est l'approche des meilleures pratiques ici? Devrais-je demander à mon code de test de modifier temporairement les informations d'enregistrement COM dans le registre afin que le code testé instancie l'un de mes objets fictifs à la place? Devrais-je injecter des unités de bibliothèque de type modifié? Quelles sont les autres approches?

Je serais particulièrement reconnaissant des exemples ou des outils pour Delphi, mais je serais tout aussi heureux de recevoir des conseils plus généraux et des explications plus poussées.

Merci,

Oliver

Était-ce utile?

La solution

L'approche traditionnelle dit que votre code client doit utiliser un wrapper, qui est responsable de l'instanciation de l'objet COM. Ce wrapper peut alors être facilement moqué.

Comme certaines parties de votre code instancient directement les objets COM, cela ne convient pas vraiment. Si vous pouvez modifier ce code, vous pouvez utiliser le modèle d'usine: ils utilisent l'usine pour créer l'objet COM. Vous pouvez vous moquer de l’usine pour renvoyer des objets alternatifs.

Vous décidez si vous souhaitez accéder à l'objet via un wrapper ou via l'interface COM d'origine. Si vous choisissez de simuler l'interface COM, n'oubliez pas d'instrumenter IUnknown :: QueryInterface dans votre simulateur, afin de savoir que vous avez simulé toutes les interfaces, en particulier si l'objet est ensuite transmis à un autre objet COM.

Vous pouvez également consulter la méthode CoTreateAsClass . Je ne l'ai jamais utilisé, mais cela pourrait faire ce dont vous avez besoin.

Autres conseils

Il s’agit de "concevoir pour la testabilité". Idéalement, vous ne devriez pas instancier directement ces objets COM, mais y accéder via une couche d'indirection pouvant être remplacée par un objet factice.

Maintenant, COM lui-même fournit un niveau d’indirection et vous pouvez fournir un objet fictif qui remplacera le vrai, mais je suppose que ce serait difficile à créer et je doute que vous obteniez beaucoup d’aide cadre moqueur existant.

J'écrirais une classe wrapper mince autour de votre objet COM tiers, qui permet de charger un objet fictif plutôt que l'objet COM réel dans la situation de test unitaire. Je le fais normalement en ayant un deuxième constructeur que j'appelle passer dans l'objet fictif. Le constructeur normal aurait chargé l'objet COM normalement.

L'article de Wikipédia contient une bonne introduction au sujet. Wikipedia artible

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top