30 Days of Automated Testing:Using PHPUnit【D18】

Mocking (Part 3): Event

WilliamP
3 min readFeb 8, 2023

30 Days of Automated Testing:Using PHPUnit【D18】 — Mocking (Part 3): Event

Today, we will continue our discussion about “Mocking”.

In Laravel, there are a few classes that have different methods for mocking compared to what we introduced in the previous two days. In this series of articles, we will show you the special mocking methods for the Event, Mail, Queue, Storage, and HTTP classes.

Let’s start with Event Mocking!

Event Mocking Functions

  • Event::fake(): This function can be called in the test code when we want to verify if an event has been triggered when executing the test target behavior, but we don't want to actually trigger the execution of the event.
  • Event::assertDispatched(): This function can be used to verify that the specified event will be triggered. It can only be used after calling Event::fake().
  • Event::assertNotDispatched(): This function can be used to verify that the specified event will not be triggered. It can only be used after calling Event::fake().
  • Event::assertNothingDispatched(): This function can be used to verify that no events have been triggered. It can only be used after calling Event::fake().

(Actually, there are other Event Mocking functions available, but the above are probably the most commonly used ones.)

Let’s see a practical demonstration!

Example:User Login

Test Target:Login Endpoint

  • database/migrations/2014_10_12_000000_create_users_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('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->string('api_token', 32)->nullable();
$table->rememberToken();
$table->timestamps();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
};
  • routes\web.php
use App\Events\UserLoggedIn;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Str;

Route::post('/login', function (Request $request) {
$email = $request->input('email');
$password = $request->input('password');

$user = User::where([
'email' => $email,
'password' => $password,
])->first();

if (empty($user)) {
return response()->json([], 401);
}

event(UserLoggedIn::class);

$user->api_token = Str::random(32);
$user->save();

return response()->json(['token' => $user->api_token]);
})->name('login');

Test Code:

<?php

namespace Tests\Feature;

use App\Events\UserLoggedIn;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Str;
use Tests\TestCase;

class EventTest extends TestCase
{
use RefreshDatabase;

public function testLoginSuccess()
{
$user = User::factory()->create([
'password' => Str::random(10),
]);

$payload = [
'email' => $user->email,
'password' => $user->password,
];

Event::fake();

$response = $this->post(route('login'), $payload);

$user->refresh();

$response->assertJson([
'api_token' => $user->api_token
]);

Event::assertDispatched(UserLoggedIn::class, 1);
}

public function testLoginFailed()
{
$user = User::factory()->create([
'password' => Str::random(10),
]);

$payload = [
'email' => $user->email,
'password' => $user->password . 'x',
];

Event::fake();

$response = $this->post(route('login'), $payload);

$response->assertUnauthorized();

Event::assertNotDispatched(UserLoggedIn::class);
}
}

The above test code tests two test cases:

  • testLoginSuccess(): In this test case function, we verify whether the UserLoggedIn event is triggered when the user logs in successfully.
  • testLoginFailed(): In this test case function, we verify that the UserLoggedIn event is not triggered when the user login fails.

Today we have introduced Event Mocking, please practice it more.

Next, let’s look at Mail Mocking.

If you liked this article or found it helpful, feel free to give it some claps and follow the author!

Reference

Articles of This Series

--

--