Hay, en algún lugar de su base de código, una línea de código que realiza la acción real de conectarse a la base de datos remota. Esta línea de código es, 9 veces en 10, una llamada a un método "incorporado" proporcionado por las bibliotecas de tiempo de ejecución específicas para su idioma y entorno. Como tal, no es "su" código y, por lo tanto, no necesita probarlo; a los fines de una prueba unitaria, puede confiar en que esta llamada al método funcionará correctamente. Lo que puede y debe probar en su conjunto de pruebas unitarias son cosas como asegurarse de que los parámetros que se utilizarán para esta llamada sean los que espera que sean, como asegurarse de que la cadena de conexión sea correcta, o la instrucción SQL o nombre del procedimiento almacenado
Este es uno de los propósitos detrás de la restricción de que las pruebas unitarias no deben abandonar su "caja de arena" en tiempo de ejecución y depender del estado externo. En realidad es bastante práctico; El propósito de una prueba unitaria es verificar que el código que escribió (o está a punto de escribir, en TDD) se comporta de la manera que pensó que lo haría. El código que no escribió, como la biblioteca que está utilizando para realizar las operaciones de su base de datos, no debe ser parte del alcance de ninguna prueba unitaria, por la sencilla razón de que no lo escribió.
En su conjunto de pruebas de integración , estas restricciones son relajadas. Ahora puedesdiseñe pruebas que toquen la base de datos, para asegurarse de que el código que escribió se reproduzca bien con el código que no escribió. Sin embargo, estos dos conjuntos de pruebas deben permanecer separados porque su conjunto de pruebas unitarias es más efectivo cuanto más rápido se ejecute (por lo que puede verificar rápidamente que todas las afirmaciones hechas por los desarrolladores sobre su código aún se mantienen), y casi por definición, una prueba de integración es más lento en órdenes de magnitud debido a las dependencias agregadas en recursos externos. Deje que el robot de compilación se encargue de ejecutar su suite de integración completa cada pocas horas, ejecutando las pruebas que bloquean los recursos externos, para que los desarrolladores no se pisen los pies al ejecutar estas mismas pruebas localmente. Y si la construcción se rompe, ¿y qué? Se le da mucha más importancia a garantizar que el build-bot nunca falle una compilación de lo que probablemente debería ser.
Ahora, cuán estrictamente puede cumplir esto depende de su estrategia exacta para conectarse y consultar la base de datos. En muchos casos en los que debe usar el marco de acceso a datos "básico", como los objetos SqlConnection y SqlStatement de ADO.NET, un método completo desarrollado por usted puede consistir en llamadas a métodos integrados y otro código que depende de tener un conexión de base de datos, por lo que lo mejor que puede hacer en esta situación es burlarse de toda la función y confiar en sus conjuntos de pruebas de integración. También depende de qué tan dispuesto esté a diseñar sus clases para permitir que se reemplacen líneas de código específicas para fines de prueba (como la sugerencia de Tobi del patrón de Método de plantilla, que es bueno porque permite "simulacros parciales"
Si su modelo de persistencia de datos se basa en el código de su capa de datos (como desencadenantes, procesos almacenados, etc.), simplemente no hay otra forma de ejercer el código que usted mismo está escribiendo que desarrollar pruebas que vivan dentro de la capa de datos o crucen límite entre el tiempo de ejecución de su aplicación y el DBMS. Un purista diría que este patrón, por esta razón, debe evitarse en favor de algo como un ORM. No creo que vaya tan lejos; Incluso en la era de las consultas integradas en el lenguaje y otras operaciones de persistencia dependientes del dominio verificadas por el compilador, veo el valor de bloquear la base de datos solo para las operaciones expuestas a través del procedimiento almacenado, y por supuesto, dichos procedimientos almacenados deben verificarse utilizando pruebas Pero, tales pruebas no son pruebas unitarias . Son integracion pruebas
Si tiene un problema con esta distinción, generalmente se basa en una gran importancia otorgada a la "cobertura de código" completa, también conocida como "cobertura de prueba unitaria". Desea asegurarse de que cada línea de su código esté cubierta por una prueba unitaria. Un noble objetivo en su cara, pero digo tonterías; esa mentalidad se presta a antipatrones que se extienden mucho más allá de este caso específico, como escribir pruebas sin afirmaciones que se ejecutan pero no ejercentu codigo. Estos tipos de ejecuciones finales únicamente por el bien de los números de cobertura son más dañinos que relajar su cobertura mínima. Si desea asegurarse de que cada línea de su base de código se ejecute mediante alguna prueba automatizada, entonces eso es fácil; cuando calcule métricas de cobertura de código, incluya las pruebas de integración. Incluso podría ir un paso más allá y aislar estas disputadas pruebas "Itino" ("Integración solo de nombre"), y entre su conjunto de pruebas unitarias y esta subcategoría de pruebas de integración (que aún debería ejecutarse razonablemente rápido) debería obtener maldición casi cerca de la cobertura total.