Comment puis-je tester un service en symfony2?
Depuis que je suis en train de travailler avec les services, cette question peut-être un problème avec l'injection de dépendance dans symfony. Actuellement, je suis en train de tester une fonctionnalité simple, dans mon service via phpunit test et je reçois l'erreur suivante:
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
De l'erreur, il est évident que je suis en train de créer une instance de mon service et le bon argument n'est pas passé, alors soufflet est à mes services.fichier 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"]
Soufflet est mon service que j'ai construit:
<?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));
}
}
Mon fichier de test est indiqué ici:
<?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);
}
}
Enfin, mes services sont inscrits ci-dessous dans le dossier app/config.fichier yml:
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: "@CaremonkMainSiteBundle/Resources/config/services.yml" }
# Other config.yml stuff
Je n'ai pas de dépendance que bien et j'espère que mon interprétation de celle-ci, comme indiqué dans ce post est proche de ce que symfony avait à l'esprit. S'il vous plaît laissez-moi savoir ce que je fais mal, afin que je puisse tester mon service.
Vous devez vous connecter pour publier un commentaire.
Dans votre cas de test, vous n'allez pas obtenir quoi que ce soit dans votre constructeur - vous pouvez configurer l'objet que vous souhaitez tester dans un setupBeforeClass ou méthode de configuration, par exemple
(Note également que vous n'avez pas besoin de configurer votre test de classes de services, de sorte que vous pouvez supprimer votre geo_test de services de services.yml)
Une fois que vous avez fait cela, vous devriez être en mesure d'exécuter votre cas de test avec quelque chose comme
Si votre sont ne va pas contrôleurs de test (avec le client, parce que contrôleur appelé comme cela utiliser un nouveau conteneur) de votre classe de test devrait étendre simplement KernelTestCase (Symfony\Bundle\FrameworkBundle\Test). Pour démarrer le noyau & obtenir les services que vous pouvez faire qqch de ce genre dans votre configuration de test:
Plus d'infos:
http://symfony.com/doc/current/testing/doctrine.html
Notes:
setUp
méthode au lieu desetUpBeforeClass
(comme dans l'acceptation de réponse).static::$kernel
(après le démarrage).Si vous ne voulez pas de faire des tests dans une application, mais dans un autonome bundle, je vous suggère de jeter un oeil à la réponse détaillée de cette question.