stringtranslate.com

Objeto simulado

En informática , un objeto simulado es un objeto que imita un objeto de producción de manera limitada. Un programador podría utilizar un objeto simulado como doble de prueba para las pruebas de software . Un objeto simulado también se puede utilizar en programación genérica .

Analogía

Un objeto simulado puede ser útil para el probador de software, como un diseñador de automóviles utiliza un muñeco de prueba de choque para simular un ser humano en el impacto de un vehículo.

Motivación

En una prueba unitaria , los objetos simulados pueden simular el comportamiento de objetos reales complejos y, por lo tanto, son útiles cuando un objeto real no es práctico o imposible de incorporar a una prueba unitaria. Si un objeto tiene alguna de las siguientes características, puede resultar útil utilizar un objeto simulado en su lugar:

Por ejemplo, un programa de despertador que hace que suene una campana a una hora determinada podría obtener la hora actual de un servicio horario. Para comprobarlo, el test deberá esperar hasta la hora de alarma para saber si ha sonado correctamente el timbre. Si se utiliza un servicio de hora simulada en lugar del servicio de tiempo real, se puede programar para proporcionar la hora de timbre (o cualquier otra hora) independientemente de la hora real, de modo que el programa del despertador se pueda probar de forma aislada.

Detalles técnicos

Los objetos simulados tienen la misma interfaz que los objetos reales que imitan, lo que permite que un objeto cliente no sepa si está utilizando un objeto real o un objeto simulado. Muchos marcos de trabajo de objetos simulados disponibles permiten al programador especificar qué métodos se invocarán en un objeto simulado, en qué orden, qué parámetros se les pasarán y qué valores se devolverán. Por lo tanto, el comportamiento de un objeto complejo como un socket de red puede ser imitado por un objeto simulado, lo que permite al programador descubrir si el objeto que se está probando responde adecuadamente a la amplia variedad de estados en los que pueden encontrarse dichos objetos simulados.

Simulacros, falsificaciones y talones

Las definiciones de simulacro, falso y trozo no son consistentes en la literatura. [1] [2] [3] [4] [5] [6] No obstante, todos representan un objeto de producción en un entorno de prueba al exponer la misma interfaz.

Independientemente del nombre, la forma más simple devuelve respuestas preestablecidas (como en un código auxiliar de método ) y la forma más compleja imita la lógica completa de un objeto de producción.

Un objeto de prueba de este tipo podría contener afirmaciones para examinar el contexto de cada llamada. Por ejemplo, un objeto simulado podría afirmar el orden en el que se llaman sus métodos o afirmar la coherencia de los datos entre las llamadas a métodos.

En el libro The Art of Unit Testing [7] los simulacros se describen como un objeto falso que ayuda a decidir si una prueba falló o pasó al verificar si se produjo una interacción con un objeto. Todo lo demás se define como un trozo. En ese libro, las falsificaciones son cualquier cosa que no sea real y que, según su uso, puede ser un talón o una burla .

Establecer expectativas

Considere un ejemplo en el que se ha burlado de un subsistema de autorización. El objeto simulado implementa un método isUserAllowed(task : Task) : boolean[8] para que coincida con el de la clase de autorización real. Se obtienen muchas ventajas si también se expone una propiedad que no está presente en la clase real. Esto permite que el código de prueba establezca fácilmente la expectativa de que a un usuario se le otorgará permiso o no en la siguiente llamada y, por lo tanto, probar fácilmente el comportamiento del resto del sistema en cualquier caso.isAllowed : boolean

De manera similar, las configuraciones de solo simulacro podrían garantizar que las llamadas posteriores al subsistema provoquen que se produzca una excepción , se cuelgue sin responder o regrese null, etc. Por lo tanto, es posible desarrollar y probar comportamientos del cliente para condiciones de falla realistas en el back-end. subsistemas finales , así como de sus respuestas esperadas. Sin un sistema simulado tan simple y flexible, probar cada una de estas situaciones puede resultar demasiado laborioso para poder considerarlas adecuadamente.

Escribir cadenas de registro

Es posible que el método de un objeto de base de datos simulado save(person : Person)no contenga mucho código de implementación (si es que contiene alguno). Podría verificar la existencia y quizás la validez del objeto Persona pasado para guardar (ver discusión falsa vs. simulada más arriba), pero más allá de eso podría no haber otra implementación.

Es una oportunidad perdida. El método simulado podría agregar una entrada a una cadena de registro público. La entrada no necesita ser más que "Persona guardada", [9] : 146–7  o puede incluir algunos detalles de la instancia del objeto persona, como un nombre o ID. Si el código de prueba también verifica el contenido final de la cadena de registro después de varias series de operaciones que involucran la base de datos simulada, entonces es posible verificar que en cada caso se haya realizado exactamente el número esperado de guardados de la base de datos. Esto puede encontrar errores que de otro modo serían invisibles y que afectan el rendimiento, por ejemplo, cuando un desarrollador, nervioso por perder datos, ha codificado llamadas repetidas save()donde solo una habría sido suficiente.

Uso en desarrollo basado en pruebas

Los programadores que trabajan con el método de desarrollo basado en pruebas (TDD) utilizan objetos simulados al escribir software. Los objetos simulados cumplen los requisitos de interfaz y sustituyen a los reales más complejos; por lo tanto, permiten a los programadores escribir y probar funcionalidades unitarias en un área sin llamar a clases complejas subyacentes o colaborativas . [9] : 144–5  El uso de objetos simulados permite a los desarrolladores centrar sus pruebas en el comportamiento del sistema bajo prueba sin preocuparse por sus dependencias. Por ejemplo, probar un algoritmo complejo basado en múltiples objetos que se encuentran en estados particulares se puede expresar claramente utilizando objetos simulados en lugar de objetos reales.

Aparte de los problemas de complejidad y los beneficios obtenidos de esta separación de preocupaciones , existen problemas prácticos de velocidad involucrados. Desarrollar un software realista utilizando TDD puede implicar fácilmente varios cientos de pruebas unitarias. Si muchos de estos inducen la comunicación con bases de datos, servicios web y otros sistemas fuera de proceso o en red , entonces el conjunto de pruebas unitarias rápidamente se volverá demasiado lento para ejecutarse con regularidad. Esto, a su vez, conduce a malos hábitos y a la renuencia del desarrollador a mantener los principios básicos de TDD.

Cuando los objetos simulados se reemplazan por objetos reales, la funcionalidad de un extremo a otro necesitará más pruebas. Serán pruebas de integración en lugar de pruebas unitarias.

Limitaciones

El uso de objetos simulados puede vincular estrechamente las pruebas unitarias con la implementación del código que se está probando. Por ejemplo, muchos marcos de objetos simulados permiten al desarrollador verificar el orden y la cantidad de veces que el objeto real que se está probando invocó los métodos de objetos simulados; Por lo tanto, la refactorización posterior del código que se está probando podría provocar que la prueba falle incluso aunque todos los métodos del objeto simulado todavía obedezcan el contrato de la implementación anterior. Esto ilustra que las pruebas unitarias deberían probar el comportamiento externo de un método en lugar de su implementación interna. El uso excesivo de objetos simulados como parte de un conjunto de pruebas unitarias puede resultar en un aumento dramático en la cantidad de mantenimiento que se debe realizar en las pruebas mismas durante la evolución del sistema a medida que se lleva a cabo la refactorización. El mantenimiento inadecuado de dichas pruebas durante la evolución podría permitir que se pasen por alto errores que de otro modo serían detectados por pruebas unitarias que utilizan instancias de clases reales. Por el contrario, simplemente burlarse de un método puede requerir mucha menos configuración que configurar una clase real completa y, por lo tanto, reducir las necesidades de mantenimiento.

Los objetos simulados tienen que modelar con precisión el comportamiento del objeto del que se burlan, lo que puede ser difícil de lograr si el objeto del que se burla proviene de otro desarrollador o proyecto o si ni siquiera se ha escrito todavía. Si el comportamiento no se modela correctamente, entonces las pruebas unitarias pueden registrar una aprobación incluso aunque se produzca una falla en el tiempo de ejecución en las mismas condiciones que la prueba unitaria, lo que hace que la prueba unitaria sea inexacta. [10]

Ver también

Referencias

  1. ^ "Prácticas recomendadas de pruebas unitarias con .NET Core y .NET Standard: hablemos el mismo idioma (falso, stubs y simulacros)". Documentos de Microsoft . Archivado desde el original el 3 de septiembre de 2022.
  2. ^ D'Arcy, Hamlet (21 de octubre de 2007). "Los simulacros y los talones no son espías". detrás de los tiempos . Archivado desde el original el 20 de junio de 2017.
  3. ^ "Simulacros, falsificaciones, talones y muñecos". XUnitPatterns.com . Archivado desde el original el 17 de enero de 2024.
  4. ^ "¿Cuál es la diferencia entre un simulacro y un talón?". Desbordamiento de pila . Archivado desde el original el 4 de julio de 2022.
  5. ^ "¿Cuál es la diferencia entre fingir, burlarse y aplastar?".
  6. ^ Plumas, Michael (2005). "Sentido y separación". Trabajar eficazmente con código heredado . Nueva Jersey: Prentice Hall. pag. 23 y siguientes. ISBN 0-13-117705-2.
  7. ^ Osherove, Roy (2009). "Pruebas de interacción con objetos simulados y siguientes". El arte de las pruebas unitarias . Manning. ISBN 978-1-933988-27-6.
  8. ^ Estos ejemplos utilizan una nomenclatura similar a la utilizada en Unified Modeling Language.
  9. ^ ab Beck, Kent (2003). Desarrollo basado en pruebas con el ejemplo . Boston: Addison Wesley. ISBN 0-321-14653-0.
  10. ^ InJava.com para burlarse | O'Reilly Medios

enlaces externos