test symfonytestslistener simple querybuilder not kerneltestcase exist does php web-services symfony dependency-injection

php - symfonytestslistener - ¿Cómo puedo probar un servicio en symfony2?



symfony test querybuilder (3)

Como estoy trabajando con servicios, esta pregunta puede terminar siendo un problema con la inyección de dependencia en Symfony. Actualmente estoy tratando de probar una característica simple en mi servicio a través de la prueba phpunit y sigo recibiendo el siguiente error:

PHP Catchable fatal error: Argument 1 passed to Caremonk/MainSiteBundle/Tests/Services/GeoTest::__construct() must be an instance of Caremonk/MainSiteBundle/Tests/Services/Geo, none given, called in /usr/share/nginx/html/caremonk/vendor/phpunit/phpunit/PHPUnit/Framework/TestSuite.php on line 473 and defined in /usr/share/nginx/html/caremonk/src/Caremonk/MainSiteBundle/Tests/Services/GeoTest.php on line 14

A partir del error, es obvio que intento crear una instancia de mi servicio y no se está transmitiendo el argumento correcto, así que debajo está mi archivo services.yml:

#src/Caremonk/MainSiteBundle/Resources/config/services.yml parameters: caremonk_main_site.geo.class: Caremonk/MainSiteBundle/Services/Geo caremonk_main_site.geo_test.class: Caremonk/MainSiteBundle/Tests/Services/GeoTest services: geo: class: %caremonk_main_site.geo.class% arguments: [] geo_test: class: %caremonk_main_site.geo_test.class% arguments: ["@geo"]

Bellow es mi servicio que he construido:

<?php //src/Caremonk/MainSiteBundle/Services/Geo.php namespace Caremonk/MainSiteBundle/Services; use Symfony/Bundle/FrameworkBundle/Controller/Controller; use Symfony/Component/HttpFoundation/Request; class Geo extends Controller { public $pi80; public $latRad; public $lngRad; public function __construct() { $this->pi80 = M_PI / 180; } // Takes longitude and latitude and converts them into their respective radians // We also set our class properties to these values public function setCoordinates($lat,$lng) { $this->latRad = $lat * $this->pi80; $this->lngRad = $lng * $this->pi80; } public function distance($lat2, $lng2, $miles = true) { $lat1 = $this->latRad; $lng1 = $this->lngRad; $lat2 *= $pi80; $lng2 *= $pi80; $r = 6372.797; // mean radius of Earth in km $dlat = ($lat2 - $lat1)/2; $dlng = ($lng2 - $lng1)/2; $a = sin($dlat) * sin($dlat) + cos($lat1) * cos($lat2) * sin($dlng) * sin($dlng); $c = 2 * atan2(sqrt($a), sqrt(1 - $a)); $km = $r * $c; return ($miles ? ($km * 0.621371192) : $km); } // This function returns the minimum latitude in radians public function min_lat($lat,$lng,$dis) { $dis /= .62137119; $ratio = $dis/6372.797; return asin(sin($lat)*cos($ratio) + cos($lat)*sin($ratio)*cos(M_PI)); } // This function returns the max latitude in radians public function max_lat($lat,$lng,$dis) { $dis /= .62137119; $ratio = $dis/6372.797; return asin(sin($lat)*cos($ratio) + cos($lat)*sin($ratio)*cos(0)); } // This function returns max longitude in radians public function max_lon($lat,$lng,$dis) { $dis /= .62137119; $ratio = $dis/6372.797; return $lng + atan2(sin(M_PI/2)*sin($ratio)*cos($lat),cos($ratio)-sin($lat)*sin($lat)); } // This function returns min longitude in radians public function min_lon($lat,$lng,$dis) { $dis /= .62137119; $ratio = $dis/6372.797; return $lng + atan2(sin(M_PI*1.5)*sin($ratio)*cos($lat),cos($ratio)-sin($lat)*sin($lat)); } }

Mi archivo de prueba se muestra aquí:

<?php //src/Caremonk/MainSiteBundle/Tests/Services/GeoTest.php namespace Caremonk/MainSiteBundle/Tests/Services; use Caremonk/MainSiteBundle/Services; use Symfony/Bundle/FrameworkBundle/Test/WebTestCase; use Symfony/Component/DependencyInjection/ContainerBuilder; class GeoTest extends WebTestCase { public $geo; public function __construct(Geo $geo) { $this->geo = $geo; } public function testSetCoordinates() { $this->geo->setCoordinates(4,5); //print $geoService->distance(6,5); } }

Por último, mis servicios se registran a continuación en el archivo app / config.yml:

imports: - { resource: parameters.yml } - { resource: security.yml } - { resource: "@CaremonkMainSiteBundle/Resources/config/services.yml" } # Other config.yml stuff

No obtengo la dependencia tan bien y espero que mi interpretación de la misma como se muestra en esta publicación sea similar a lo que Symfony tenía en mente. Por favor, hágame saber lo que estoy haciendo mal para poder probar mi servicio.


En su caso de prueba, no obtendrá nada en su constructor; puede configurar el objeto que desea probar en un método setupBeforeClass o setup, por ejemplo

public static function setUpBeforeClass() { //start the symfony kernel $kernel = static::createKernel(); $kernel->boot(); //get the DI container self::$container = $kernel->getContainer(); //now we can instantiate our service (if you want a fresh one for //each test method, do this in setUp() instead self::$geo = self::$container->get(''geo''); }

(Tenga en cuenta que tampoco necesita configurar sus clases de prueba como servicios, por lo que puede eliminar su servicio geo_test de services.yml)

Una vez que hayas hecho eso, deberías poder ejecutar tu caso de prueba con algo como

cd /root/of/project phpunit -c app src/Caremonk/MainSiteBundle/Tests/Services/GeoTest.php


Si no desea realizar pruebas en una aplicación sino en un paquete independiente, le sugiero que eche un vistazo a la respuesta muy detallada de esta question .


Si no va a probar los controladores (con el cliente), su clase de prueba solo debe extender KernelTestCase (Symfony / Bundle / FrameworkBundle / Test). Para arrancar el kernel y obtener servicios, puede hacer algo así en su configuración de prueba:

use Symfony/Bundle/FrameworkBundle/Test/KernelTestCase; class MyTest extends KernelTestCase { public function setUp() { $kernel = self::bootKernel(); $this->geo = $kernel->getContainer()->get(''geo''); } ... }

Más información: http://symfony.com/doc/current/testing/doctrine.html

Notas:

  1. Para tener kernel y servicios nuevos para cada prueba, recomiendo utilizar el método setUp lugar de setUpBeforeClass (como en la respuesta aceptada).
  2. El kernel siempre es accesible vía static::$kernel (después del arranque).
  3. También funciona en Symfony 3 y 4.