Introducción
Imaginemos que estamos desarrollando una pequeña aplicación web en la versión Laravel superior a 6 y queremos escribir pruebas para ella.
El contenido del artículo se detalla a continuación:
- Descripción del dominio
- Creación de aplicaciones
- Creación de entidad
- Pruebas de escritura
- Problema
- Decisión
Descripción del dominio
Desarrollaremos una tienda en línea en la que ciertos usuarios pueden hacer un pedido determinado. De lo anterior se deduce que las principales entidades del área temática serán el usuario, el pedido y los bienes. Existe una relación de uno a muchos entre el usuario y el pedido, es decir, el usuario puede tener muchos pedidos y el pedido solo tiene un usuario (se requiere un usuario para el pedido). Existe una relación de muchos a muchos entre el pedido y los bienes, porque los bienes pueden estar en diferentes pedidos y el pedido puede consistir en muchos bienes. Por simplicidad, omitimos productos y nos enfocamos solo en usuarios y pedidos.
Creación de aplicaciones
Las aplicaciones Laravel son muy fáciles de construir utilizando el paquete de creador de aplicaciones . Después de instalarlo, la creación de una nueva aplicación se ajusta a un comando:
laravel new shop
Creación de entidad
, — . 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 — !
Eso es todo lo que quería compartir. A menudo me encuentro con el problema de que es necesario controlar el número de entidades después de alguna acción dentro del sistema, y la implementación estándar de fábrica realmente no hace frente a esto.
Estaré encantado de escuchar tus trucos que utilizas cuando desarrollas en Laravel o PHP.