Hace algún tiempo, trabajamos en un proyecto que utilizaba Drupal 7, el cual, entre otros requisitos, demandaba pruebas automáticas para demostrar la funcionalidad del sistema. Drupal viene con un módulo de pruebas integrado llamado SimpleTest. Sin embargo, al utilizarlo nos dimos cuenta de que no sería suficiente para satisfacer los requerimientos del proyecto.
El código fuente de Drupal 7 está basado en procedimientos, lo que significa que no está orientado a objetos. El estilo de programación conocido como "Drupal Way" también sigue este patrón, lo cual genera dificultades para realizar pruebas unitarias. Esto se debe a que las funciones en Drupal 7 están estrechamente interconectadas, lo que hace que sea complicado probarlas de manera aislada.
Para resolver el problema, decidimos adoptar tres enfoques clave:
Decidimos usar PHPUnit por varias razones:
Para realizar pruebas unitarias, necesitábamos cambiar la arquitectura del código. La programación orientada a objetos es ideal para encapsular funcionalidad en objetos que se puedan probar de manera discreta. A continuación, mostramos cómo hicimos este cambio.
Este enfoque depende directamente de Guzzle para hacer la solicitud. Para aplicar programación orientada a objetos, transformamos esta función en un objeto:
Y luego reescribimos la función original para usar este objeto:
Una de las ventajas de este enfoque es que ahora podemos escribir pruebas unitarias para verificar el comportamiento del objeto Owner. Aquí mostramos un ejemplo de cómo hacerlo:
En este punto, nos enfrentamos a una nueva cuestión: la función getPropertyList depende de una conexión remota a través de Guzzle. Pero, ¿qué pasa si no podemos o no queremos usar esa conexión para las pruebas unitarias automáticas? La solución es usar mocks para simular la conexión.
Inyectamos una conexión mock en el objeto Owner:
Ahora que tenemos las pruebas unitarias funcionando, necesitamos inyectar la conexión Guzzle en el objeto Owner dentro de la aplicación. Aquí entra en juego el contenedor de inyección de dependencias.Optamos por usar el módulo inject, que utiliza el contenedor de Symfony, el cual también es utilizado en Drupal 8. El siguiente código muestra cómo implementamos este contenedor para gestionar dependencias:
Luego, en nuestra función, inyectamos el servicio:
En resumen, nuestra estrategia consistió en utilizar PHPUnit, programación orientada a objetos, y inyección de dependencias para lograr un sistema de pruebas unitarias repetibles y automatizables. Esta solución nos permitió resolver las dificultades de realizar pruebas unitarias en un código orientado a procedimientos, asegurando que nuestro sistema sea más robusto y fácil de mantener.