نسخه:

تقلید

معرفی

هنگام آزمایش برنامه های لاراول، ممکن است بخواهید جنبه های خاصی از برنامه خود را "تقلید" کنید تا در طول یک آزمایش خاص اجرا نشوند. به عنوان مثال، هنگام آزمایش کنترلری که رویدادی را ارسال می کند، ممکن است بخواهید شنوندگان رویداد را تقلید کنید تا در طول آزمایش اجرا نشوند. این به شما امکان می دهد فقط پاسخ HTTP کنترلر را بدون نگرانی در مورد اجرای شنوندگان رویداد آزمایش کنید، زیرا شنوندگان رویداد را می توان در مورد آزمایشی خود آزمایش کرد.

لاراول کمک هایی برای تقلید وقایع، مشاغل و نماهای بیرون از جعبه فراهم می کند. این کمک‌ها در درجه اول یک لایه راحتی روی Mockery ارائه می‌کنند، بنابراین شما مجبور نیستید به صورت دستی فراخوانی‌های پیچیده روش Mockery را انجام دهید. شما همچنین می توانید از Mockery یا PHPUnit برای ساختن تقلید یا جاسوسان خود استفاده کنید.

اشیاء تقلید

هنگام تقلید کردن یک شی که قرار است از طریق کانتینر سرویس لاراول به برنامه شما تزریق شود، باید نمونه تقلید شده خود را به عنوان یک instance اتصال به کانتینر متصل کنید. این به کانتینر دستور می دهد که به جای ساختن خود شی، از نمونه تقلید شده شما از شی استفاده کند:

use App\Service;
use Mockery;
 
$this->instance(Service::class, Mockery::mock(Service::class, function ($mock) {
$mock->shouldReceive('process')->once();
}));

برای راحت‌تر کردن این کار، می‌توانید از mock روشی استفاده کنید که توسط کلاس تست پایه لاراول ارائه شده است:

use App\Service;
 
$this->mock(Service::class, function ($mock) {
$mock->shouldReceive('process')->once();
});

ممکن است زمانی از این روش استفاده کنید partialMock که فقط نیاز به تقلید چند روش از یک شی دارید. متدهایی که تقلید نمی شوند در صورت فراخوانی به طور معمول اجرا می شوند:

use App\Service;
 
$this->partialMock(Service::class, function ($mock) {
$mock->shouldReceive('process')->once();
});

به طور مشابه، اگر می‌خواهید روی یک شی جاسوسی کنید، کلاس آزمایشی پایه لاراول روشی را spy به عنوان یک پوشش مناسب در اطراف Mockery::spy متد ارائه می‌کند:

use App\Service;
 
$this->spy(Service::class, function ($mock) {
$mock->shouldHaveReceived('process');
});

مسیر تقلبی

به عنوان جایگزینی برای تقلید، می توانید از روش Bus نما fake برای جلوگیری از ارسال کارها استفاده کنید. هنگام استفاده از تقلبی، اظهارات پس از اجرای کد مورد آزمایش انجام می شود:

<?php
 
namespace Tests\Feature;
 
use App\Jobs\ShipOrder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Support\Facades\Bus;
use Tests\TestCase;
 
class ExampleTest extends TestCase
{
public function testOrderShipping()
{
Bus::fake();
 
// Perform order shipping...
 
Bus::assertDispatched(ShipOrder::class, function ($job) use ($order) {
return $job->order->id === $order->id;
});
 
// Assert a job was not dispatched...
Bus::assertNotDispatched(AnotherJob::class);
}
}

رویداد جعلی

به عنوان جایگزینی برای تقلید، می توانید از روش Event نما fake برای جلوگیری از اجرای همه شنوندگان رویداد استفاده کنید. سپس می توانید ادعا کنید که رویدادها ارسال شده اند و حتی داده هایی را که دریافت کرده اند بررسی کنید. هنگام استفاده از تقلبی، اظهارات پس از اجرای کد مورد آزمایش انجام می شود:

<?php
 
namespace Tests\Feature;
 
use App\Events\OrderFailedToShip;
use App\Events\OrderShipped;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Support\Facades\Event;
use Tests\TestCase;
 
class ExampleTest extends TestCase
{
/**
* Test order shipping.
*/
public function testOrderShipping()
{
Event::fake();
 
// Perform order shipping...
 
Event::assertDispatched(OrderShipped::class, function ($e) use ($order) {
return $e->order->id === $order->id;
});
 
// Assert an event was dispatched twice...
Event::assertDispatched(OrderShipped::class, 2);
 
// Assert an event was not dispatched...
Event::assertNotDispatched(OrderFailedToShip::class);
}
}

پس از تماس Event::fake() ، هیچ شنونده رویدادی اجرا نمی شود. بنابراین، اگر آزمایش‌های شما از کارخانه‌های مدل استفاده می‌کنند که به رویدادها متکی هستند، مانند ایجاد UUID در طول creating رویداد یک مدل، باید Event::fake() پس از استفاده از کارخانه‌های خود تماس بگیرید.

جعل کردن زیر مجموعه ای از رویدادها

اگر فقط می خواهید شنوندگان رویداد را برای مجموعه خاصی از رویدادها جعل کنید، می توانید آنها را به روش fake یا ارسال کنید fakeFor :

/**
* Test order process.
*/
public function testOrderProcess()
{
Event::fake([
OrderCreated::class,
]);
 
$order = factory(Order::class)->create();
 
Event::assertDispatched(OrderCreated::class);
 
// Other events are dispatched as normal...
$order->update([...]);
}

تقلبی رویدادهای محدوده

اگر فقط می خواهید شنوندگان رویداد را برای بخشی از آزمایش خود جعل کنید، می توانید از fakeFor روش زیر استفاده کنید:

<?php
 
namespace Tests\Feature;
 
use App\Events\OrderCreated;
use App\Order;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Event;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Tests\TestCase;
 
class ExampleTest extends TestCase
{
/**
* Test order process.
*/
public function testOrderProcess()
{
$order = Event::fakeFor(function () {
$order = factory(Order::class)->create();
 
Event::assertDispatched(OrderCreated::class);
 
return $order;
});
 
// Events are dispatched as normal and observers will run ...
$order->update([...]);
}
}

ایمیل جعلی

می توانید از روش Mail نما fake برای جلوگیری از ارسال نامه استفاده کنید. سپس می‌توانید ادعا کنید که ایمیل‌ها برای کاربران ارسال شده‌اند و حتی داده‌هایی را که دریافت کرده‌اند بررسی کنید. هنگام استفاده از تقلبی، اظهارات پس از اجرای کد مورد آزمایش انجام می شود:

<?php
 
namespace Tests\Feature;
 
use App\Mail\OrderShipped;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Support\Facades\Mail;
use Tests\TestCase;
 
class ExampleTest extends TestCase
{
public function testOrderShipping()
{
Mail::fake();
 
// Assert that no mailables were sent...
Mail::assertNothingSent();
 
// Perform order shipping...
 
Mail::assertSent(OrderShipped::class, function ($mail) use ($order) {
return $mail->order->id === $order->id;
});
 
// Assert a message was sent to the given users...
Mail::assertSent(OrderShipped::class, function ($mail) use ($user) {
return $mail->hasTo($user->email) &&
$mail->hasCc('...') &&
$mail->hasBcc('...');
});
 
// Assert a mailable was sent twice...
Mail::assertSent(OrderShipped::class, 2);
 
// Assert a mailable was not sent...
Mail::assertNotSent(AnotherMailable::class);
}
}

اگر پست‌های پستی را برای تحویل در پس‌زمینه در صف قرار می‌دهید، باید از assertQueued روش به جای استفاده از assertSent :

Mail::assertQueued(...);
Mail::assertNotQueued(...);

اعلان جعلی

می توانید از روش Notification نما fake برای جلوگیری از ارسال اعلان ها استفاده کنید. سپس می توانید ادعا کنید که اعلان ها برای کاربران ارسال شده است و حتی داده های دریافتی آنها را بررسی کنید. هنگام استفاده از تقلبی، اظهارات پس از اجرای کد مورد آزمایش انجام می شود:

<?php
 
namespace Tests\Feature;
 
use App\Notifications\OrderShipped;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Notifications\AnonymousNotifiable;
use Illuminate\Support\Facades\Notification;
use Tests\TestCase;
 
class ExampleTest extends TestCase
{
public function testOrderShipping()
{
Notification::fake();
 
// Assert that no notifications were sent...
Notification::assertNothingSent();
 
// Perform order shipping...
 
Notification::assertSentTo(
$user,
OrderShipped::class,
function ($notification, $channels) use ($order) {
return $notification->order->id === $order->id;
}
);
 
// Assert a notification was sent to the given users...
Notification::assertSentTo(
[$user], OrderShipped::class
);
 
// Assert a notification was not sent...
Notification::assertNotSentTo(
[$user], AnotherNotification::class
);
 
// Assert a notification was sent via Notification::route() method...
Notification::assertSentTo(
new AnonymousNotifiable, OrderShipped::class
);
 
// Assert Notification::route() method sent notification to the correct user...
Notification::assertSentTo(
new AnonymousNotifiable,
OrderShipped::class,
function ($notification, $channels, $notifiable) use ($user) {
return $notifiable->routes['mail'] === $user->email;
}
);
}
}

صف جعلی

به عنوان جایگزینی برای تقلید، می توانید از روش Queue نما fake برای جلوگیری از قرار گرفتن مشاغل در صف استفاده کنید. سپس می توانید ادعا کنید که کارها به صف کشیده شده اند و حتی داده هایی را که دریافت کرده اند بررسی کنید. هنگام استفاده از تقلبی، اظهارات پس از اجرای کد مورد آزمایش انجام می شود:

<?php
 
namespace Tests\Feature;
 
use App\Jobs\AnotherJob;
use App\Jobs\FinalJob;
use App\Jobs\ShipOrder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Support\Facades\Queue;
use Tests\TestCase;
 
class ExampleTest extends TestCase
{
public function testOrderShipping()
{
Queue::fake();
 
// Assert that no jobs were pushed...
Queue::assertNothingPushed();
 
// Perform order shipping...
 
Queue::assertPushed(ShipOrder::class, function ($job) use ($order) {
return $job->order->id === $order->id;
});
 
// Assert a job was pushed to a given queue...
Queue::assertPushedOn('queue-name', ShipOrder::class);
 
// Assert a job was pushed twice...
Queue::assertPushed(ShipOrder::class, 2);
 
// Assert a job was not pushed...
Queue::assertNotPushed(AnotherJob::class);
 
// Assert a job was pushed with a given chain of jobs, matching by class...
Queue::assertPushedWithChain(ShipOrder::class, [
AnotherJob::class,
FinalJob::class
]);
 
// Assert a job was pushed with a given chain of jobs, matching by both class and properties...
Queue::assertPushedWithChain(ShipOrder::class, [
new AnotherJob('foo'),
new FinalJob('bar'),
]);
 
// Assert a job was pushed without a chain of jobs...
Queue::assertPushedWithoutChain(ShipOrder::class);
}
}

ذخیره سازی تقلبی

روش Storage نما fake به شما این امکان را می دهد که به راحتی یک دیسک جعلی تولید کنید که در ترکیب با ابزارهای تولید فایل کلاس UploadedFile ، آزمایش آپلود فایل را تا حد زیادی ساده می کند. مثلا:

<?php
 
namespace Tests\Feature;
 
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;
 
class ExampleTest extends TestCase
{
public function testAlbumUpload()
{
Storage::fake('photos');
 
$response = $this->json('POST', '/photos', [
UploadedFile::fake()->image('photo1.jpg'),
UploadedFile::fake()->image('photo2.jpg')
]);
 
// Assert one or more files were stored...
Storage::disk('photos')->assertExists('photo1.jpg');
Storage::disk('photos')->assertExists(['photo1.jpg', 'photo2.jpg']);
 
// Assert one or more files were not stored...
Storage::disk('photos')->assertMissing('missing.jpg');
Storage::disk('photos')->assertMissing(['missing.jpg', 'non-existing.jpg']);
}
}

به طور پیش فرض، این fake روش تمام فایل های موجود در فهرست موقت خود را حذف می کند. اگر می خواهید این فایل ها را نگه دارید، می توانید به جای آن از روش "persistentFake" استفاده کنید.

نماها

برخلاف فراخوانی‌های روش استاتیک سنتی، نماها ممکن است مورد تقلید قرار گیرند. این مزیت بزرگی نسبت به روش‌های استاتیک سنتی دارد و همان تست‌پذیری را در صورت استفاده از تزریق وابستگی به شما می‌دهد. هنگام آزمایش، ممکن است اغلب بخواهید تماس با نمای لاراول را در یکی از کنترلرهای خود تقلید کنید. به عنوان مثال، عمل کنترلر زیر را در نظر بگیرید:

<?php
 
namespace App\Http\Controllers;
 
use Illuminate\Support\Facades\Cache;
 
class UserController extends Controller
{
/**
* Show a list of all users of the application.
*
* @return Response
*/
public function index()
{
$value = Cache::get('key');
 
//
}
}

Cache ما می‌توانیم با استفاده از shouldReceive روشی که نمونه‌ای از ماک تقلید را برمی‌گرداند ، تماس را به نما تقلید کنیم . از آنجایی که نماها در واقع توسط کانتینر سرویس لاراول حل و فصل می شوند ، آزمایش پذیری بسیار بیشتری نسبت به یک کلاس استاتیک معمولی دارند. به عنوان مثال، بیایید فراخوانی خود را به روش Cache نما تقلید کنیم get :

<?php
 
namespace Tests\Feature;
 
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Support\Facades\Cache;
use Tests\TestCase;
 
class UserControllerTest extends TestCase
{
public function testGetIndex()
{
Cache::shouldReceive('get')
->once()
->with('key')
->andReturn('value');
 
$response = $this->get('/users');
 
// ...
}
}

شما نباید Request نما را تقلید کنید. در عوض، ورودی مورد نظر خود را به روش‌های کمکی HTTP مانند get و post هنگام اجرای آزمایش ارسال کنید. به همین ترتیب، به جای تقلید Config نما، Config::set روش را در تست های خود فراخوانی کنید.