introduction
Imaginons que nous développons une petite application web sur une version Laravel supérieure à 6 et que nous voulons écrire des tests pour celle-ci.
Le contenu de l'article est donné ci-dessous:
- Description du domaine
- Création d'application
- Création d'entité
- Tests d'écriture
- ProblĂšme
- Décision
Description du domaine
Nous dĂ©velopperons une boutique en ligne dans laquelle certains utilisateurs pourront passer une certaine commande. De ce qui prĂ©cĂšde, nous obtenons que les principales entitĂ©s du domaine seront l'utilisateur, la commande et les marchandises. Il existe une relation un-Ă -plusieurs entre l'utilisateur et la commande, c'est-Ă -dire que l'utilisateur peut avoir plusieurs commandes et que la commande n'a qu'un seul utilisateur (un utilisateur est requis pour la commande). Il existe une relation plusieurs Ă plusieurs entre la commande et les marchandises, car les marchandises peuvent ĂȘtre dans des commandes diffĂ©rentes et la commande peut ĂȘtre composĂ©e de plusieurs marchandises. Par souci de simplicitĂ©, nous omettons les produits et nous nous concentrons uniquement sur les utilisateurs et les commandes.
Création d'application
Les applications Laravel sont trÚs faciles à construire à l' aide du package du créateur d'application . AprÚs l'avoir installé, la création d'une nouvelle application tient dans une seule commande:
laravel new shop
Création d'entité
, â . Laravel , . , . :
php artisan make:model Order -m -f
App/, database/migrations/ database/factories/.
. , . - :
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateOrdersTable extends Migration
{
public function up()
{
Schema::create('orders', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')
->onDelete('cascade');
});
}
public function down()
{
Schema::dropIfExists('orders');
}
}
. fillable :
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Order extends Model
{
protected $fillable = ['user_id'];
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}
. , , id.
<?php
use App\Order;
use App\User;
use Faker\Generator as Faker;
$factory->define(Order::class, function (Faker $faker) {
return [
'user_id' => factory(User::class)->create()->id
];
});
, .
, Laravel PHPUnit . :
php artisan make:test OrderTest
tests/Feature/. RefreshDatabase.
â1.
<?php
namespace Tests\Feature;
use App\Order;
use App\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
class OrderTest extends TestCase
{
use RefreshDatabase;
public function order_factory_can_create_order()
{
$order = factory(Order::class)->create();
$this->assertInstanceOf(Order::class, $order);
}
}
!
â2.
public function order_should_have_user_relation()
{
$order = factory(Order::class)->create();
$this->assertNotEmpty($order->user_id);
$this->assertInstanceOf(User::class, $order->user);
}
!
â3. ,
public function we_can_provide_user_id_to_order_factory()
{
$user = factory(User::class)->create();
$order = factory(Order::class)->create(['user_id' => $user->id]);
$this->assertEquals($user->id, $order->user_id);
}
!
, , . , , .
â4. ,
public function when_we_create_one_order_one_user_should_be_created()
{
$user = factory(User::class)->create();
$order = factory(Order::class)->create(['user_id' => $user->id]);
$this->assertEquals($user->id, $order->user_id);
$this->assertEquals(1, User::count());
}
! , . ? .
, , â . , , . . , , . , .
, . PHP , n- â func_get_arg(), . , () Faker, â , create() . , , () . , , . :
$factory->define(Order::class, function (Faker $faker) {
$passedArguments = func_get_arg(1);
return [
'user_id' => function () use ($passedArguments) {
if (! array_key_exists('user_id', $passedArguments)) {
return factory(User::class)->create()->id;
}
}
];
});
â4 â !
C'est tout ce que je voulais partager. Je rencontre souvent le problÚme qu'il est nécessaire de contrÎler le nombre d'entités aprÚs une action à l'intérieur du systÚme, et l'implémentation d'usine standard ne résout pas vraiment cela.
Je serai heureux d'entendre vos astuces que vous utilisez lors du développement en Laravel ou PHP.