La plupart de mes tests unitaires utilisent WithoutMiddleware pour tester le contrôleur et le point de terminaison des ressources. Cependant, la liaison de modèle d'itinéraire est un intergiciel, de sorte que les contrôleurs n'obtiennent pas les modèles dont ils ont besoin.Comment faire pour que la liaison de modèle de route fonctionne dans Laravel pendant les tests unitaires?
0
A
Répondre
0
Créez un fournisseur de services qui s'exécute uniquement pendant les tests. - assurez-vous d'abord que vous avez défini l'option APP_ENV dans phpunit.xml - créez ensuite un fournisseur de services pour laravel comme celui ci-dessous. (Ne pas oublier d'ajouter dans la section fournisseurs de config/app.php)
phpunit.xml
...<php>
<env name="APP_ENV" value="testing"/>
...
</php>...
config/app.php
...providers=>[..., App\Providers\PhpUnitServiceProvider::class, ...]
app/fournisseurs/PhpUnitServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class PhpUnitServiceProvider extends ServiceProvider{
/**
* Map of classes you want route-model binding to work
* based on a variable name in the route.
*
* example: http://localhost/bank-accounts/{bank_account}
*
* @var array
*/
private static $map = [
\App\Financial\BankAccount::class => 'bank_account',
];
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot(){
//
}
/**
* We need to simulate route-model binding.
*
* @return void
*/
public function register(){
//
if(env('APP_ENV') == 'testing'){
$classes = array_keys(static::$map);
foreach($classes as $class){
$this->app->bind($class, function ($app) use ($class){
return self::factory($class, $app);
});
}
}
}
private static function factory($class, $app){
if(empty(static::$map[$class])){
return null;
}
$request = request();
$target = static::$map[$class];
if(empty($request->$target)){
return null;
}
$id = $request->$target;
return $class::find($id);
}
}