介绍
假设我们正在使用高于6的Laravel版本开发一个小型Web应用程序,并希望为其编写测试。
该文章的内容如下:
- 域说明
- 应用程式建立
- 实体创建
- 编写测试
- 问题
- 决断
域说明
我们将建立一个在线商店,某些用户可以在其中下订单。从上面我们可以得到,主题区域的主要实体将是用户,订单和商品。用户与订单之间存在一对多的关系,即该用户可以有多个订单,并且该订单只有一个用户(该订单需要一个用户)。订单和商品之间存在多对多关系,因为商品可以处于不同的订单中,并且订单可以包含许多商品。为简单起见,我们忽略了产品,只关注用户和订单。
应用程式建立
Laravel应用程序使用application maker软件包非常容易构建。安装后,创建一个新应用程序适合一个命令:
laravel new shop
实体创建
, — . 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 — !
这就是我要分享的全部。我经常遇到这样的问题,即在系统内部执行某些操作后必须控制实体的数量,而标准工厂实现并不能真正解决这个问题。
我很高兴听到您在Laravel或PHP中进行开发时使用的技巧。