Comparte:
Test: crear nuestro propio metodo json para agregar los headers
Que tal Jorge mucho gusto,
Tengo una duda, a que se debe que si realizo el return $this->json() entrara en un lup infinito sino que debo hacerlo al padre del json
Gracias de antemano por los detalles
Tengo una duda, a que se debe que si realizo el return $this->json() entrara en un lup infinito sino que debo hacerlo al padre del json
Gracias de antemano por los detalles
Tenemos el Trait MakesHttpRequests de Laravel
<?php namespace Illuminate\\Foundation\\Testing\\Concerns; trait MakesHttpRequests { public function json($method, $uri, array $data = [], array $headers = []) { $files = $this->extractFilesFromDataArray($data); $content = json_encode($data); $headers = array_merge([ 'CONTENT_LENGTH' => mb_strlen($content, '8bit'), 'CONTENT_TYPE' => 'application/json', 'Accept' => 'application/json', ], $headers); return $this->call( $method, $uri, [], $this->prepareCookiesForJsonRequest(), $files, $this->transformHeadersToServerVars($headers), $content ); } }
Este método es el que se utiliza para hacer peticiones en los TESTS, y este archivo viene con Laravel, así que no lo podemos editar.
Por este motivo creamos un nuevo Trait MakesJsonApiRequests
<?php namespace Illuminate\\Foundation\\Testing\\Concerns; trait MakesJsonApiRequests { public function json($method, $uri, array $data = [], array $headers = []): TestResponse { if ($this->addJsonApiHeaders) { $headers['accept'] = 'application/vnd.api+json'; if ($method === 'POST' || $method === 'PATCH') { $headers['content-type'] = 'application/vnd.api+json'; } } if ($this->formatJsonApiDocument) { if (! isset($data['data'])) { $formattedData = $this->getFormattedData($uri, $data); } } return parent::json($method, $uri, $formattedData ?? $data, $headers); } }
En la clase abstracta, TestCase estamos utilizando este Trait
<?php namespace Tests; use Illuminate\\Foundation\\Testing\\TestCase as BaseTestCase; abstract class TestCase extends BaseTestCase { use CreatesApplication, MakesJsonApiRequests; }
Todos los tests de la carpeta Feature, se extienden a esta clase TestCase, por lo que heredan todos lo métodos del trait y de la clase base TestCase.
Ahora, vamos a ver un ejemplo de uno de los tests que tenemos:
<?php namespace Tests\\Feature\\Articles; use Tests\\TestCase; use App\\Models\\Article; use Illuminate\\Foundation\\Testing\\RefreshDatabase; class ListArticlesTest extends TestCase { use RefreshDatabase; /** @test */ public function can_fetch_articles() { $this->json(route('api.v1.articles.index')); ... } }
Debemos entender que la palabra (o keyword) $this hace referencia a la clase ListArticlesTest y al ejecutar $this->json() se va a buscar un método llamado json dentro de la clase ListArticlesTest y como podemos observar, no existe dicho método, sin embargo, al estar extendiendo a la clase TestCase que a su vez utiliza el trait MakesJsonApiRequests que sí contiene la clase json entonces esa es la que se va a ejecutar.
Ahora, vamos a concentrarnos en el trait MakesJsonApiRequests
<?php namespace Illuminate\\Foundation\\Testing\\Concerns; trait MakesJsonApiRequests { public function json($method, $uri, array $data = [], array $headers = []): TestResponse { // ... // La pregunta es por qué llamamos al parent::json en lugar de this->json return parent::json($method, $uri, $formattedData ?? $data, $headers); } }
En este contexto, parent hace referencia a la clase abstracta TestCase que contiene otro método json
Si hacemos lo siguiente se creará un loop infinito y la aplicación se detendrá:
<?php namespace Illuminate\\Foundation\\Testing\\Concerns; trait MakesJsonApiRequests { public function json($method, $uri, array $data = [], array $headers = []): TestResponse { // ... // En este caso se va a llamar al mismo método json, una y otra vez... return $this->json($method, $uri, $formattedData ?? $data, $headers); } }
En este caso estamos llamando al método json del trait MakesJsonApiRequests y dentro del método, estamos llamando nuevamente a sí mismo, al mismo método json por lo que se genera el bucle infinito.