Pruebas Unitarias en Laravel: Mutadores y Campos Virtuales

Clase 7 de 24Curso Básico de Testing con PHP y Laravel

Contenido del curso

Conceptos

Proyecto

Resumen

Probar que los datos se transforman correctamente antes de almacenarse es una práctica fundamental en cualquier aplicación robusta con Laravel. Cuando un usuario ingresa información con mayúsculas o espacios, el sistema debe garantizar que esa información se normalice de forma consistente. Aquí se explica cómo escribir pruebas unitarias para validar mutadores y accesores (campos virtuales) en un modelo de Laravel, siguiendo el enfoque de escribir primero el test y luego la implementación.

¿Cómo crear un test unitario para un modelo que aún no existe?

El primer paso consiste en generar el archivo de prueba antes de crear el modelo. Esto sigue la filosofía de test-driven development (TDD): primero defines el comportamiento esperado y después escribes el código que lo cumple.

Se ejecuta el comando para crear el test unitario [01:00]:

  • php artisan make:test Models/PostTest --unit genera la clase de prueba en la carpeta correspondiente.
  • El flag --unit indica que se trata de un test unitario, no de un test de integración.
  • El modelo Post todavía no existe, pero ya se referencia desde el test.

Dentro del test se instancia un nuevo objeto Post y se le asigna un valor al campo name con mayúsculas y minúsculas mezcladas, por ejemplo: "Proyecto en PHP". La aserción verifica que el valor almacenado se haya convertido completamente a minúsculas [02:18].

Al ejecutar las pruebas con php artisan test, el resultado falla en la línea donde se referencia el modelo inexistente. Ese error es precisamente lo esperado: el test guía la implementación.

¿Qué es un mutador y cómo se implementa en el modelo?

Un mutador es un método dentro del modelo que altera el valor de un atributo antes de que se almacene. En Laravel, se define con la convención set + nombre del atributo + Attribute [03:30].

Para crear el modelo se ejecuta php artisan make:model Post. Dentro de la clase Post se agrega el método:

php public function setNameAttribute($value) { $this->attributes['name'] = strtolower($value); }

  • La función strtolower() convierte toda la cadena a minúsculas.
  • Cualquier valor que se asigne al campo name pasará por esta transformación automáticamente.
  • Al ejecutar nuevamente las pruebas, el test pasa correctamente [04:30].

Este patrón permite garantizar la consistencia de los datos sin depender de que el usuario ingrese la información en un formato específico.

¿Cómo funciona un accesor o campo virtual en Laravel?

Un accesor genera un campo que no existe físicamente en la base de datos, pero que se calcula a partir de otros atributos. Se le conoce también como campo virtual. En este ejercicio se crea un accesor para el campo slug [05:00].

El test verifica que al asignar "Proyecto en PHP" como nombre, el campo slug devuelva "proyecto-en-php": todo en minúsculas y con los espacios reemplazados por guiones.

La implementación en el modelo utiliza la convención get + nombre del campo + Attribute:

php public function getSlugAttribute() { return str_replace(' ', '-', strtolower($this->name)); }

  • strtolower() convierte a minúsculas.
  • str_replace() sustituye los espacios por guiones.
  • El campo name ya pasa por el mutador, así que llega en minúsculas; la función refuerza esa transformación para el slug.

Para ejecutar un test específico se puede usar un filtro con el nombre del método [06:08]:

bash php artisan test --filter=test_get_slug

El resultado confirma que el campo virtual se genera correctamente.

¿Por qué conviene ejecutar todas las pruebas después de cada cambio?

Al finalizar la implementación, se ejecutan todas las pruebas del proyecto para confirmar que ningún cambio previo se haya roto [06:50]:

  • Los tests de modelos (set_name, get_slug) pasan sin error.
  • Los tests existentes de helpers, validación de email y rutas (home, acerca de) siguen funcionando.
  • Esto demuestra la importancia de una suite de pruebas completa: cada nuevo código se valida sin comprometer lo anterior.

Escribir pruebas para mutadores y accesores no solo valida la lógica de transformación, sino que documenta el comportamiento esperado del modelo. Si en el futuro alguien modifica la lógica del slug o del campo name, las pruebas alertarán de inmediato sobre cualquier regresión. ¿Ya estás aplicando TDD en tus proyectos con Laravel? Comparte tu experiencia.