¿Cómo se prueba unitariamente el código que interactúa y crea instancias de objetos COM de terceros?

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

Pregunta

Uno de los mayores problemas que actualmente me impide sumergirme a toda velocidad en las pruebas unitarias es que un porcentaje realmente grande del código que escribo depende en gran medida de objetos COM de terceros de diferentes fuentes que también tienden a interactuar entre sí (yo Estoy escribiendo complementos para Microsoft Office usando varias bibliotecas auxiliares si necesita saberlo).

Sé que probablemente debería usar objetos simulados, pero ¿cómo lo haría exactamente en este caso?Puedo ver que es relativamente fácil cuando solo tengo que pasar una referencia a un objeto ya existente, pero algunas de mis rutinas crean instancias de objetos COM externos y luego, a veces, los pasan a algún otro objeto COM externo de una biblioteca diferente.

¿Cuál es el enfoque de mejores prácticas aquí?¿Debo hacer que mi código de prueba cambie temporalmente la información de registro COM en el registro para que el código probado cree una instancia de uno de mis objetos simulados?¿Debo inyectar unidades de biblioteca de tipo modificado?¿Qué otros enfoques existen?

Estaría especialmente agradecido por ejemplos o herramientas para Delphi, pero también estaría feliz con consejos más generales y explicaciones de alto nivel.

Gracias,

óliver

¿Fue útil?

Solución

El enfoque tradicional dice que su código de cliente debe usar un contenedor, que es responsable de crear una instancia del objeto COM.Luego se puede burlar fácilmente de este envoltorio.

Debido a que tiene partes de su código que crean instancias de los objetos COM directamente, esto realmente no encaja.Si puedes cambiar ese código, puedes usar el patrón de fábrica:utilizan la fábrica para crear el objeto COM.Puedes burlarte de la fábrica para devolver objetos alternativos.

Depende de usted si se accede al objeto a través de un contenedor o mediante la interfaz COM original.Si elige simular la interfaz COM, recuerde instrumentar IUnknown::QueryInterface en su simulación, para saber que se ha burlado de todas las interfaces, especialmente si el objeto se pasa luego a algún otro objeto COM.

Alternativamente, consulte el CoTreateAsClass método.Nunca lo he usado, pero podría hacer lo que necesitas.

Otros consejos

Todo se reduce a "diseñar para la capacidad de prueba".Lo ideal sería no crear instancias de esos objetos COM directamente, sino acceder a ellos a través de una capa de indirección que pueda ser reemplazada por un objeto simulado.

Ahora, COM en sí proporciona un nivel de direccionamiento indirecto y usted podría proporcionar un objeto simulado que proporcionara un sustituto del real, pero sospecho que sería complicado crearlo y dudo que obtenga mucha ayuda de un marco simulado existente. .

Escribiría una clase contenedora delgada alrededor de su objeto COM de terceros, que tiene la capacidad de cargar un objeto simulado en lugar del objeto COM real en la situación de prueba unitaria.Normalmente hago esto teniendo un segundo constructor al que llamo pasando el objeto simulado.El constructor normal simplemente habría cargado el objeto COM normalmente.

El artículo de Wikipedia tiene una buena introducción al tema.Wikipedia articulable

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top