2023-12-18|閱讀時間 ‧ 約 32 分鐘

PHPUnit 自動化測試大作戰【CH20】

今天來看 Queue Mocking 吧!

Queue Mocking 函數

  • Queue::fake():當我們希望在執行測試目標行為時,想驗證某個 Job 類別是否有被派送至佇列中,但又不要真的觸發 Job 入列時,可在測試程式碼中呼叫此函數。
  • Queue::assertPushed():可驗證指定的 Job 類別是否被配送至佇列。需在執行 Queue::fake() 後方可使用。
  • Queue::assertPushedOn():可驗證指定的 Job 類別是否被配送至指定的佇列。需在執行 Queue::fake()後方可使用。
  • Queue::assertNotPushed():可驗證指定的 Job 類別是否未被配送至佇列。需在執行 Queue::fake() 後方可使用。
  • Queue::assertNothingPushed():可驗證是否無 Job 類別被配送至佇列。需在執行 Queue::fake() 後方可使用。

接下來讓我們實際演練看看吧!

範例:文章瀏覽計數

測試目標:文章瀏覽記錄端點

  • database/migrations/2022_10_02_174939_create_articles_table.php
<?php

use Illuminate\Database\Migrations\Migration;

use Illuminate\Database\Schema\Blueprint;

use Illuminate\Support\Facades\Schema;

return new class extends Migration{

/** * Run the migrations. * * @return void */

public function up() {

Schema::create('articles', function (Blueprint $table) {

$table->id();

$table->text('content');

$table->integer('page_views');

$table->timestamps();

}); } /** * Reverse the migrations. * * @return void */

public function down() {

Schema::dropIfExists('articles');

}};
  • app/Models/Article.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;

use Illuminate\Database\Eloquent\Model;

class Article extends Model{

use HasFactory;

protected $fillable = [

'content',

'page_views',

];}
  • database/factories/ArticleFactory.php
<?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;

/** * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Article> */

class ArticleFactory extends Factory{

/** * Define the model's default state. * * @return array<string, mixed> */

public function definition() {

return [

'content' => $this->faker->text,

'page_views' => 0,

]; }}
  • app/Jobs/AddArticlePageViewJob.php
<?php

namespace App\Jobs;

use App\Models\Article;

use Illuminate\Bus\Queueable;

use Illuminate\Contracts\Queue\ShouldBeUnique;

use Illuminate\Contracts\Queue\ShouldQueue;

use Illuminate\Foundation\Bus\Dispatchable;

use Illuminate\Queue\InteractsWithQueue;

use Illuminate\Queue\SerializesModels;

class AddArticlePageViewJob implements ShouldQueue{

use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

private $article;

/** * Create a new job instance. * * @return void */

public function __construct(Article $article) {

$this->article = $article;

} /** * Execute the job. * * @return void */

public function handle() {

$this->article->page_views += 1;

$this->article->save();

}}
  • routes\api.php
<?php

use App\Jobs\AddArticlePageViewJob;

use App\Models\Article;

use Illuminate\Http\Request;

use Illuminate\Support\Facades\Route;

Route::post('/article/{id}/page-view', function (Request $request, $id) {

$article = Article::find($id);

if (empty($article)) {

return response()->json([], 404);

} AddArticlePageViewJob::dispatch($article)->onQueue('redis');

return response('', 200);

});
  • 測試程式碼:
<?php

namespace Tests\Feature;

use App\Jobs\AddArticlePageViewJob;

use App\Models\Article;

use Illuminate\Foundation\Testing\RefreshDatabase;

use Illuminate\Support\Facades\Queue;

use Tests\TestCase;

class QueueTest extends TestCase{

use RefreshDatabase;

public function testDispatchAddArticlePageViewJob() {

$article = Article::factory()->create();

Queue::fake();

$response = $this->post(route('add-article-page-views', ['id' => $article->id]));

$response->assertOk();

Queue::assertPushedOn('redis', AddArticlePageViewJob::class);

} public function testNotDispatchAddArticlePageViewJob() {

$article = Article::factory()->create();

Queue::fake();

$response = $this->post(route('add-article-page-views', ['id' => $article->id . '0']));

$response->assertNotFound();

Queue::assertNotPushed(AddArticlePageViewJob::class);

}}

以上測試程式碼,測試了 2 種測試案例:

  • testDispatchAddArticlePageViewJob():在這個測試案例函數中,我們驗證了當文章瀏覽記錄端點被請求,且文章存在時,有發送AddArticlePageViewJob 這個 Job 類別。
  • testNotDispatchAddArticlePageViewJob():在這個測試案例函數中,我們驗證了當文章瀏覽記錄端點被請求,且文章不存在時,沒有發送AddArticlePageViewJob 這個 Job 類別。

以上就是今天所介紹的 Queue Mocking,大家可以多加演練。

下一篇讓我們來看看Storage Mocking 與 HTTP Mocking。

如果您喜歡這篇文章,歡迎加入追蹤以接收新文章通知 😄

參考資料

本系列文章目錄

分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.