En esta entrega de nuestro ejercicio de creación de foros impulsado por pruebas, agregaremos la capacidad para que un usuario explore hilos en función de un canal determinado. Comenzaremos agregando una prueba para navegar por distintos hilos. En el camino nos encontraremos con muchos errores que nos guiarán sobre los pasos a seguir. Durante el proceso de creación de nuestra primera prueba, veremos la necesidad de crear una prueba unitaria más específica para que la prueba de funciones pase. Cambiaremos la configuración de enlace de nuestro modelo de ruta para hacer uso de un slug en lugar de una identificación, y también crearemos un nuevo método en el modelo de canal. ¡En sus marcas, listos, fuera!


Agregar una prueba para examinar subprocesos distintos

Ahora que hemos agregado soporte para canales en nuestro foro, tendría sentido que realmente podamos navegar según el canal. Si estamos navegando por un URI determinado que pertenece a un canal determinado, deberíamos ver solo los hilos asociados con ese canal. Empecemos a preparar una prueba para eso. Una primera puñalada en esto puede verse así:

Ok, probémoslo.

vagrant @ homestead: ~ / Code / forumio $ phpunit --filter test_a_user_can_filter_threads_according_to_channel
PHPUnit 6.5.5 por Sebastian Bergmann y colaboradores.

E 1/1 (100%)

Tiempo: 733 ms, memoria: 8,00 MB

Hubo 1 error:

1) TestsFeatureReadThreadsTest :: test_a_user_can_filter_threads_according_to_channel
IlluminateDatabaseQueryException: SQLSTATE [HY000]: Error general: 1 tabla de canales no tiene una columna llamada channel_id (SQL: insertar en los valores de "canales" ("nombre", "slug", "channel_id", "updated_at", "created_at") (cupiditate , cupiditate, 2, 2018-01-04 19:06:33, 2018-01-04 19:06:33))

Hmm, espera. Eso no parece correcto. Está bien, parece que estropeamos el código de prueba. Primero necesitamos crear un canal y luego dos hilos. Nuestra primera puñalada tuvo un error en el que creamos 3 canales. Arreglemos eso.

¿Estamos bien ahora? Veamos.

vagrant @ homestead: ~ / Code / forumio $ phpunit --filter test_a_user_can_filter_threads_according_to_channel
PHPUnit 6.5.5 por Sebastian Bergmann y colaboradores.

F 1/1 (100%)

Tiempo: 778 ms, memoria: 8,00 MB

Hubo 1 falla:

1) TestsFeatureReadThreadsTest :: test_a_user_can_filter_threads_according_to_channel
No se pudo afirmar que 'el html' contiene "Quibusdam et sapiente impedit rerum unde eligendi.".

Bueno, obtenemos un error, pero no es realmente el error que esperábamos. Para ser claros, estamos esperando un error de ruta no encontrada. Quizás este sea uno de esos casos en los que necesitamos alternar el manejo de excepcionesProbemos eso.

Este es el error que estábamos buscando.

vagrant @ homestead: ~ / Code / forumio $ phpunit --filter test_a_user_can_filter_threads_according_to_channel
PHPUnit 6.5.5 por Sebastian Bergmann y colaboradores.

E 1/1 (100%)

Tiempo: 720 ms, memoria: 8,00 MB

Hubo 1 error:

1) TestsFeatureReadThreadsTest :: test_a_user_can_filter_threads_according_to_channel
SymfonyComponentHttpKernelExceptionNotFoundHttpException: GET http: // localhost / threads / sed

Con eso en su lugar, ¿cómo solucionamos este tipo de error? Por supuesto, agregamos la ruta necesaria al archivo de rutas. Aquí vamos:

Sabemos incluso antes de ejecutar la prueba que vamos a necesitar actualizar el método index () en la clase ThreadsController para manejar esta nueva ruta, así que centrémonos en eso ahora.


Dos por uno

Lo que estamos configurando aquí es la capacidad del método index () en la clase ThreadsController para manejar dos escenarios por nosotros. Por un lado, sabemos que normalmente se usa un método index () para darnos todo un recurso en particular. También podemos usar este método con un argumento para que cuando se proporcione, solo se devuelva un tipo específico de recurso. Entonces, lo que queremos que suceda es que, si no se proporciona ningún canal slug, obtendremos todos los hilos. Si se proporciona un canal slug, solo queremos los hilos asociados con ese canal slug. Así es como podemos hacer que funcione.

Ahora podemos ejecutar nuestra prueba y ver que está funcionando, ¡genial!

vagrant @ homestead: ~ / Code / forumio $ phpunit --filter test_a_user_can_filter_threads_according_to_channel
PHPUnit 6.5.5 por Sebastian Bergmann y colaboradores.

. 1/1 (100%)

Tiempo: 1,32 segundos, memoria: 10,00 MB

OK (1 prueba, 2 afirmaciones)

Refactorización para utilizar el enlace de modelo de ruta

Refactoricemos cómo queremos que se lea el código, incluso si los métodos asociados aún no están presentes. Por ejemplo, si refactorizamos nuestro método de índice así:

Sabemos que el método threads () aún no existe, pero nos gusta cómo se lee el código. Así que dejaremos esto en su lugar y desarrollaremos lo que necesitamos para que funcione. Comencemos ejecutando la prueba y veamos dónde estamos.

vagrant @ homestead: ~ / Code / forumio $ phpunit --filter test_a_user_can_filter_threads_according_to_channel
PHPUnit 6.5.5 por Sebastian Bergmann y colaboradores.

E 1/1 (100%)

Tiempo: 971 ms, memoria: 8,00 MB

Hubo 1 error:

1) TestsFeatureReadThreadsTest :: test_a_user_can_filter_threads_according_to_channel
IlluminateDatabaseEloquentModelNotFoundException: No hay resultados de consulta para el modelo [AppChannel].

Parece que tenemos una excepción de modelo no encontrado. Interesante. ¿Por qué es esto? Ok, lo que está sucediendo aquí es que Route Model Binding en Laravel siempre va a buscar el modelo por su identificación en una configuración predeterminada. Nos estamos pasando una babosa para encontrar el modelo en este caso, ¿y ahora qué? Bueno, puede especificar en la clase Model usar un slug en lugar de una identificación como esta:

¡Frio! Ejecutemos la prueba de nuevo.

vagrant @ homestead: ~ / Code / forumio $ phpunit --filter test_a_user_can_filter_threads_according_to_channel
PHPUnit 6.5.5 por Sebastian Bergmann y colaboradores.

E 1/1 (100%)

Tiempo: 904 ms, memoria: 8,00 MB

Hubo 1 error:

1) TestsFeatureReadThreadsTest :: test_a_user_can_filter_threads_according_to_channel
BadMethodCallException: llamada al método no definido IlluminateDatabaseQueryBuilder :: threads ()

Bien no está mal. Arreglamos el otro error, pero ahora tenemos un error de método indefinido. Sin embargo, esperábamos esto ya que sabemos que el método threads () aún no está definido en el modelo. ¡Podemos construirlo ahora e incluir otra prueba! Esta será una prueba unitaria para el canal.

Aquí creamos un canal y luego un hilo en ese canal. Luego afirmamos que la colección de subprocesos en ese canal tiene el subproceso. Ejecutamos la prueba y obtenemos una falla esperada ya que necesitamos un método.

vagrant @ homestead: ~ / Code / forumio $ phpunit --filter test_a_channel_consists_of_threads
PHPUnit 6.5.5 por Sebastian Bergmann y colaboradores.

E 1/1 (100%)

Tiempo: 840 ms, memoria: 8,00 MB

Hubo 1 error:

1) TestsFeatureChannelTest :: test_a_channel_consists_of_threads
Error: la llamada a una función miembro contiene () en nulo

/home/vagrant/Code/forumio/tests/Unit/ChannelTest.php:19

¡ERRORES!
Pruebas: 1, afirmaciones: 0, errores: 1.

Ahora podemos seguir adelante y construir ese método en nuestro modelo de esta manera:

¡Podemos ejecutar la prueba unitaria nuevamente y ahora debería pasar!

vagrant @ homestead: ~ / Code / forumio $ phpunit --filter test_a_channel_consists_of_threads
PHPUnit 6.5.5 por Sebastian Bergmann y colaboradores.

. 1/1 (100%)

Tiempo: 687 ms, memoria: 8,00 MB

OK (1 prueba, 1 afirmación)

Fantástico. ¡Ahora deberíamos poder volver atrás y ejecutar nuestra prueba de funciones y deberíamos estar bien allí también!

vagrant @ homestead: ~ / Code / forumio $ phpunit --filter test_a_user_can_filter_threads_according_to_channel
PHPUnit 6.5.5 por Sebastian Bergmann y colaboradores.

. 1/1 (100%)

Tiempo: 1,05 segundos, memoria: 10,00 MB

OK (1 prueba, 2 afirmaciones)

Ejecución de todas las pruebas

Estamos en un buen lugar ahora. Agregamos una función, agregamos algunas pruebas para respaldarla, hicimos algunos refactores y esas pruebas están pasando bien. Así que hemos terminado y listo ... ¿O lo estamos? Es una buena idea ejecutar el conjunto completo de pruebas cada vez que agregue algunas funciones nuevas al código base. Necesitamos asegurarnos de no afectar nada en otros lugares. Ok, sigamos adelante y hagamos eso.

vagabundo @ homestead: ~ / Código / forumio $ phpunit
PHPUnit 6.5.5 por Sebastian Bergmann y colaboradores.

F ................... 20/20 (100%)

Tiempo: 2,47 segundos, memoria: 12,00 MB

Hubo 1 falla:

1) TestsFeatureCreateThreadsTest :: test_guest_can_not_create_threads
El código de estado de respuesta [404] no es un código de estado de redireccionamiento.
No se pudo afirmar que lo falso es verdadero.

/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestResponse.php:93
/home/vagrant/Code/forumio/tests/Feature/CreateThreadsTest.php:16

¡FALLOS!
Pruebas: 20, afirmaciones: 32, fallos: 1.

UH oh. Tenemos un problema. Una de nuestras pruebas ahora está fallando. Necesitaremos arreglar esto antes de seguir adelante. Parece que la prueba de test_guest_can_not_create_threads () está fallando, así que inspeccionaremos esa prueba.

Movemos la ruta que habíamos creado más abajo en el archivo de rutas y esto debería aclarar las cosas.

La ejecución del conjunto completo de pruebas muestra que ahora todo está pasando. ¡Excelente!

vagabundo @ homestead: ~ / Código / forumio $ phpunit
PHPUnit 6.5.5 por Sebastian Bergmann y colaboradores.

.................... 20/20 (100%)

Tiempo: 2,34 segundos, memoria: 12,00 MB

OK (20 pruebas, 35 afirmaciones)

Visualización de todos los hilos en un menú desplegable

Podemos hacer algunas ediciones en nuestro archivo de diseño app.blade.php para que tengamos un enlace a todos los hilos, así como un menú desplegable para todos los canales que existen. Luego, el usuario puede hacer clic en cada canal individual en el menú desplegable y solo se mostrarán los hilos asociados con ese canal. Consulte el marcado resaltado a continuación que lo configurará para usted.

Efectivamente, ahora tenemos un buen menú desplegable con todos los canales de prueba que se han configurado en nuestro proyecto hasta ahora. ¡Agradable!
rellenar el menú desplegable con php


Cómo filtrar modelos por otro modelo

En este tutorial configuramos con éxito la capacidad de filtrar hilos por canales. Lo bueno es que todo está respaldado por pruebas también. Si sabe cómo hacer esto con un tipo de modelo, puede aplicarlo fácilmente a otros escenarios. Aquí usamos canales para filtrar hilos. El mismo enfoque funcionaría cuando filtra las publicaciones de blog por categorías o los hilos por etiquetas, por ejemplo. ¡Buen trabajo!