30 Days of Automated Testing:Using PHPUnit【D18】
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 callingEvent::fake()
.Event::assertNotDispatched()
: This function can be used to verify that the specified event will not be triggered. It can only be used after callingEvent::fake()
.Event::assertNothingDispatched()
: This function can be used to verify that no events have been triggered. It can only be used after callingEvent::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 theUserLoggedIn
event is triggered when the user logs in successfully.testLoginFailed()
: In this test case function, we verify that theUserLoggedIn
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!