تقلید
معرفی
هنگام آزمایش برنامه های لاراول، ممکن است بخواهید جنبه های خاصی از برنامه خود را "تقلید" کنید تا در طول یک آزمایش خاص اجرا نشوند. به عنوان مثال، هنگام آزمایش کنترلری که رویدادی را ارسال می کند، ممکن است بخواهید شنوندگان رویداد را تقلید کنید تا در طول آزمایش اجرا نشوند. این به شما امکان می دهد فقط پاسخ 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
روش را در تست های خود فراخوانی کنید.