Simulator ujian Mengejek
~
- Simulasi acara
- Simulasikan subset peristiwa
- Simulasi Pemberitahuan
- Simulasi Baris Gilir
- Simulasi Storan Simulasi Tugas
- Simulasi Acara
- Simulasi Acara Berskop Simulasi E-mel
Pengenalan
Dalam ujian aplikasi Laravel, anda mungkin mahu "mensimulasikan" gelagat ciri tertentu aplikasi, dengan itu menghalang bahagian itu daripada benar-benar melaksanakan dalam ujian. Sebagai contoh: peristiwa (Acara) akan dicetuskan semasa pelaksanaan pengawal, dengan itu menghalang acara daripada benar-benar dilaksanakan semasa menguji pengawal. Ini membolehkan anda menguji hanya respons HTTP pengawal tanpa perlu risau tentang mencetuskan peristiwa. Sudah tentu, anda juga boleh menguji logik peristiwa ini dalam ujian berasingan.
Laravel menyediakan fungsi pembantu luar kotak untuk simulasi acara, tugasan dan fasad. Fungsi ini dikapsulkan berdasarkan Mocker dan sangat mudah digunakan. Tidak perlu memanggil fungsi Olok-olok yang kompleks secara manual. Sudah tentu anda juga boleh menggunakan Mockery atau mencipta emulator anda sendiri menggunakan PHPUnit. . Ini akan memberitahu bekas untuk menggunakan contoh olok-olok objek dan bukannya membina objek sebenar:
use Mockery; use App\Service; $this->instance(Service::class, Mockery::mock(Service::class, function ($mock) { $mock->shouldReceive('process')->once(); }) );
Untuk menjadikan proses di atas lebih mudah, anda boleh menggunakan kelas kes ujian asas Laravel untuk menyediakan mock
kaedah: use App\Service;$this->mock(Service::class, function ($mock) {
$mock->shouldReceive('process')->once();
});
Task Simulation
Sebagai alternatif kepada simulasi, anda boleh menggunakan Bas
Kaedah palsu
Facade untuk menghalang tugas daripada benar-benar diedarkan untuk pelaksanaan. Apabila menggunakan palsu, pernyataan biasanya muncul di belakang kod ujian: instance
绑定到容器中。这将告诉容器使用对象的模拟实例,而不是构造对象的真身:
<?php namespace Tests\Feature; use Tests\TestCase;use App\Jobs\ShipOrder; use Illuminate\Support\Facades\Bus; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\WithoutMiddleware; class ExampleTest extends TestCase{ public function testOrderShipping() { Bus::fake(); // 执行订单发货... Bus::assertDispatched(ShipOrder::class, function ($job) use ($order) { return $job->order->id === $order->id; }); // 断言任务并未分发... Bus::assertNotDispatched(AnotherJob::class); } }
为了让以上过程更加便捷,你可以使用 Laravel 的基本测试用例类提供 mock
方法:
<?php namespace Tests\Feature; use Tests\TestCase;use App\Events\OrderShipped; use App\Events\OrderFailedToShip; use Illuminate\Support\Facades\Event; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\WithoutMiddleware; class ExampleTest extends TestCase{ /** * 测试订单发送 */ public function testOrderShipping() { Event::fake(); // 执行订单发送... Event::assertDispatched(OrderShipped::class, function ($e) use ($order) { return $e->order->id === $order->id; }); // 断言一个事件被发送了两次... Event::assertDispatched(OrderShipped::class, 2); // 未分配断言事件... Event::assertNotDispatched(OrderFailedToShip::class); } }
任务模拟
作为模拟的替代方式,你可以使用 Bus
Facade 的 fake
方法来防止任务被真正分发执行。使用 fake 的时候,断言一般出现在测试代码的后面:
/** * 测试订单流程 */ public function testOrderProcess(){ Event::fake([ OrderCreated::class, ]); $order = factory(Order::class)->create(); Event::assertDispatched(OrderCreated::class); // 其他事件照常发送... $order->update([...]); }
事件模拟
作为 mock 的替代方法,你可以使用 Event
Facade 的 fake
方法来模拟事件监听,测试的时候并不会真正触发事件监听器。然后你就可以测试断言事件运行了,甚至可以检查他们接收的数据。使用 fake 的时候,断言一般出现在测试代码的后面:
<?php namespace Tests\Feature; use App\Order;use Tests\TestCase; use App\Events\OrderCreated; use Illuminate\Support\Facades\Event; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\WithoutMiddleware; class ExampleTest extends TestCase{ /** * 测试订单流程 */ public function testOrderProcess() { $order = Event::fakeFor(function () { $order = factory(Order::class)->create(); Event::assertDispatched(OrderCreated::class); return $order; }); // 事件按正常方式发送,观察者将运行... $order->update([...]); } }
{note} 调用
Event::fake()
后不会执行事件监听。所以,你基于事件的测试必须使用工厂模型,例如,在模型的creating
事件中创建 UUID ,你应该调用Event::fake()
之后 使用工厂模型。
模拟事件的子集
如果你只想为特定的一组事件模拟事件监听器,你可以将它们传递给 fake
或 fakeFor
方法:
<?php namespace Tests\Feature; use Tests\TestCase;use App\Mail\OrderShipped; use Illuminate\Support\Facades\Mail; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\WithoutMiddleware; class ExampleTest extends TestCase{ public function testOrderShipping() { Mail::fake(); // 断言没有发送任何邮件... Mail::assertNothingSent(); // 执行订单发送... Mail::assertSent(OrderShipped::class, function ($mail) use ($order) { return $mail->order->id === $order->id; }); // 断言一条发送给用户的消息... Mail::assertSent(OrderShipped::class, function ($mail) use ($user) { return $mail->hasTo($user->email) && $mail->hasCc('...') && $mail->hasBcc('...'); }); // 断言邮件被发送两次... Mail::assertSent(OrderShipped::class, 2); // 断言没有发送邮件... Mail::assertNotSent(AnotherMailable::class); } }
Scoped 事件模拟
如果你只想为部分测试模拟事件监听,则可以使用 fakeFor
Mail::assertQueued(...); Mail::assertNotQueued(...);
Anda boleh menggunakan kaedah 如果你用后台任务执行邮件发送队列,你应该是用 你可以使用 作为模拟替代方案,你可以使用 你可以使用 {tip} 默认情况下, Tidak seperti panggilan kaedah statik tradisional, fasad juga boleh diejek. Berbanding dengan kaedah statik tradisional, ia mempunyai kelebihan yang besar Walaupun anda menggunakan suntikan kebergantungan, kebolehujiannya tidak lebih rendah daripada separuh. Dalam ujian anda, anda mungkin mahu mensimulasikan panggilan ke Fasad Laravel dalam pengawal anda. Contohnya, tingkah laku dalam pengawal di bawah: Kami boleh mensimulasikan Fasad {note} 你不能模拟 Palsu
Fasad Acara
untuk mensimulasikan pendengar acara sebenarnya tidak akan dicetuskan semasa ujian. Anda kemudiannya boleh menguji peristiwa penegasan yang berjalan dan juga memeriksa data yang mereka terima. Apabila menggunakan palsu, pernyataan biasanya muncul di belakang kod ujian: 🎜<?php
namespace Tests\Feature;
use Tests\TestCase;
use App\Notifications\OrderShipped;
use Illuminate\Support\Facades\Notification;
use Illuminate\Notifications\AnonymousNotifiable;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
class ExampleTest extends TestCase{
public function testOrderShipping()
{
Notification::fake();
// 断言没有发送通知...
Notification::assertNothingSent();
// 执行订单发送...
Notification::assertSentTo(
$user,
OrderShipped::class,
function ($notification, $channels) use ($order) {
return $notification->order->id === $order->id;
}
);
// 断言向给定用户发送了通知...
Notification::assertSentTo(
[$user], OrderShipped::class
);
// 断言没有发送通知...
Notification::assertNotSentTo(
[$user], AnotherNotification::class
);
// 断言通过 Notification::route() 方法发送通知...
Notification::assertSentTo(
new AnonymousNotifiable, OrderShipped::class
);
}
}
🎜{note} Pemantauan acara tidak akan dilaksanakan selepas memanggil
Event::fake()
. Oleh itu, ujian berasaskan acara anda mesti menggunakan model kilang, sebagai contoh, untuk mencipta UUID dalam acara creating
model, anda harus memanggil Event::fake()
< kuat> selepas itu Gunakan model kilang. 🎜Mensimulasikan subset acara
🎜Jika anda hanya mahu mensimulasikan pendengar acara untuk set acara tertentu, anda Mereka boleh dihantar kepada kaedah palsu
atau fakeFor
: 🎜<?php
namespace Tests\Feature;
use Tests\TestCase;use App\Jobs\ShipOrder;
use Illuminate\Support\Facades\Queue;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
class ExampleTest extends TestCase{
public function testOrderShipping()
{
Queue::fake();
// 断言没有任务被发送...
Queue::assertNothingPushed();
// 执行订单发送...
Queue::assertPushed(ShipOrder::class, function ($job) use ($order) {
return $job->order->id === $order->id;
});
// 断言任务进入了指定队列...
Queue::assertPushedOn('queue-name', ShipOrder::class);
// 断言任务进入2次...
Queue::assertPushed(ShipOrder::class, 2);
// 断言没有一个任务进入队列...
Queue::assertNotPushed(AnotherJob::class);
// 断言任务是由特定的通道发送的...
Queue::assertPushedWithChain(ShipOrder::class, [
AnotherJob::class,
FinalJob::class
]);
}
}
🎜🎜🎜Simulasi acara berskop
🎜Jika anda hanya mahu mensimulasikan pendengaran acara untuk sebahagian daripada ujian, anda boleh menggunakan kaedah fakeFor
: 🎜<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
class ExampleTest extends TestCase{
public function testAvatarUpload()
{
Storage::fake('avatars');
$response = $this->json('POST', '/avatar', [
'avatar' => UploadedFile::fake()->image('avatar.jpg')
]);
// 断言文件已存储...
Storage::disk('avatars')->assertExists('avatar.jpg');
// 断言文件不存在...
Storage::disk('avatars')->assertMissing('missing.jpg');
}
}
🎜🎜🎜🎜🎜🎜Simulasi e-mel
Mail
untuk mensimulasikan penghantaran e-mel. E-mel sebenarnya tidak akan dihantar semasa ujian maiil dihantar kepada Pengguna malah boleh menyemak apa yang mereka terima. Apabila menggunakan palsu, penegasan biasanya diletakkan selepas kod ujian: Mail
Facade 的 fake
方法来模拟邮件发送,测试时不会真的发送邮件,然后你可以断言 mailables 发送给了用户,甚至可以检查他们收到的内容。使用 fakes 时,断言一般放在测试代码的后面:<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Cache;
class UserController extends Controller{
/**
* 显示应用里所有用户
*
* @return Response
*/
public function index()
{
$value = Cache::get('key');
//
}
}
assertQueued
代替 assertSent
:<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Support\Facades\Cache;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
class UserControllerTest extends TestCase{
public function testGetIndex()
{
Cache::shouldReceive('get')
->once()
->with('key')
->andReturn('value');
$response = $this->get('/users');
// ...
}
}
通知模拟
Notification
Facade 的 fake
方法来模拟通知的发送,测试时并不会真的发出通知。然后你可以断言 notifications 发送给了用户,甚至可以检查他们收到的内容。使用 fakes 时,断言一般放在测试代码后面:队列模拟
Queue
Facade 的 fake
方法避免把任务真的放到队列中执行。然后你就可以断言任务已经被推送入队列了,甚至可以检查它们收到的数据。使用 fakes 时,断言一般放在测试代码的后面:存储模拟
Storage
Facade 的 fake
方法,轻松的生成一个模拟磁盘,结合 UploadedFile 类的文件生成工具,极大的简化了文件上传测试。例如:
rrreee fake
rrreeeassertQueued
dan bukannya assertSent
: palsu
untuk mensimulasikan penghantaran pemberitahuan sebenarnya tidak akan dihantar semasa ujian. Anda kemudian boleh menegaskan bahawa pemberitahuan telah dihantar kepada pengguna dan juga memeriksa perkara yang mereka terima. Apabila menggunakan palsu, penegasan biasanya diletakkan di belakang kod ujian: 🎜rrreee🎜🎜🎜Queue
Facade's fake
untuk mengelakkan sebenarnya meletakkan tugas dalam baris gilir untuk pelaksanaan. Anda kemudian boleh menegaskan bahawa tugas telah ditolak ke baris gilir dan juga memeriksa data yang mereka terima. Apabila menggunakan palsu, penegasan biasanya diletakkan di belakang kod ujian: 🎜rrreee🎜🎜🎜Storage
untuk menjana cakera simulasi dengan mudah Digabungkan dengan alat penjanaan fail kelas UploadedFile, ia sangat memudahkan ujian muat naik fail. Contohnya: 🎜rrreee🎜{tip} Secara lalai, kaedah
palsu
akan memadamkan semua fail dalam direktori sementara. Jika anda ingin menyimpan fail ini, anda boleh menggunakan "persistentFake". 🎜🎜🎜🎜🎜🎜🎜🎜Fasad
Cache
melalui kaedah shouldReceive
Fungsi ini akan mengembalikan Instance MockeryshouldReceive
方法来模拟 Cache
Facade,此函数会返回一个 Mockery 实例。由于 Facade 的调用实际是由 Laravel 的 服务容器 管理的,所以 Facade 能比传统的静态类表现出更好的可测试性。下面,让我们模拟一下 Cache
Facade 的 get
方法:Request
Facade 。相反,在运行测试时如果需要传入指定参数,请使用 HTTP 辅助函数,比如 get
和 post
。同理,请在测试时通过调用 Config::set
来模拟 Config
. Oleh kerana panggilan Facade sebenarnya diuruskan oleh bekas perkhidmatan Laravel, Facade boleh menunjukkan kebolehujian yang lebih baik daripada kelas statik tradisional. Seterusnya, mari kita simulasi kaedah get
Fasad Cache
: Request
. Sebaliknya, gunakan fungsi pembantu HTTP seperti get
dan post
jika anda perlu memasukkan parameter tertentu semasa menjalankan ujian anda. Begitu juga, sila simulasi Fasad Config
dengan memanggil Config::set
semasa ujian. LearnKu.com