به همان روشی که اقدام به یونیت تست کردن UserController
کردیم، حال در این آموزش قصد داریم اَکشنهای موجود داخل DefaultController
که جملگی مرتبط با عملیات CRUD در ارتباط با مقالات هستند را مورد آزمایش قرار دهیم. برای همین منظور، داخل پوشهٔ tests
که پیش از این ساختیم یک فایل جدید با نامی بامسمی همچون DefaultControllerTest.php
ساخته و آن را به صورت زیر تکمیل میکنیم:
<?php
use Api\Config\Database;
use Api\Models\Article;
use Api\Models\User;
use Firebase\JWT\JWT;
use PHPUnit\Framework\TestCase;
class DefaultControllerTest extends TestCase
{
public function testGettingAnArticleById()
{
$sampleArticleId = 1;
$articleModel = new Article((new Database())->connect());
$result = $articleModel->readById($sampleArticleId);
$result = $result->fetchAll(\PDO::FETCH_ASSOC);
$this->assertIsArray($result);
}
public function testGettingAllArticles()
{
$articleModel = new Article((new Database())->connect());
$result = $articleModel->read();
$result = $result->fetchAll(\PDO::FETCH_ASSOC);
$this->assertIsArray($result);
}
public function testCreatingANewArticle()
{
$tmpUserId = 1;
$token = JWT::encode([
'iat' => time(),
'iss' => 'localhost',
'exp' => time() + 60 * 60,
'userId' => $tmpUserId,
], '8dc2d81404c4ca0ba23b85b941696534');
$payload = JWT::decode($token, '8dc2d81404c4ca0ba23b85b941696534', ['HS256']);
$user = new User((new Database())->connect());
$result = $user->fetchUserById($payload->userId);
$result = $result->fetchAll(\PDO::FETCH_ASSOC);
if ($result) {
$articleModel = new Article((new Database())->connect());
$tmpParams = [
'articleTitle' => 'Title',
'articleContent' => 'Content',
'usrId' => $tmpUserId,
'catId' => 1,
];
$isInserted = $articleModel->create($tmpParams);
$this->assertTrue($isInserted);
}
}
public function testUpdatingAnArticle()
{
$tmpUserId = 1;
$tmpArticleId = 1;
$token = JWT::encode([
'iat' => time(),
'iss' => 'localhost',
'exp' => time() + 60 * 60,
'userId' => $tmpUserId,
], '8dc2d81404c4ca0ba23b85b941696534');
$payload = JWT::decode($token, '8dc2d81404c4ca0ba23b85b941696534', ['HS256']);
$user = new User((new Database())->connect());
$result = $user->fetchUserById($payload->userId);
$result = $result->fetchAll(\PDO::FETCH_ASSOC);
if ($result) {
$articleModel = new Article((new Database())->connect());
$tmpParams = [
'articleTitle' => 'New article title',
'articleContent' => 'new article content',
'usrId' => $tmpUserId,
'catId' => 2,
];
$isUpdated = $articleModel->update($tmpArticleId, $tmpParams);
$this->assertTrue($isUpdated);
}
}
public function testDeletingAnArticle()
{
$tmpUserId = 1;
$tmpArticleId = 10;
$token = JWT::encode([
'iat' => time(),
'iss' => 'localhost',
'exp' => time() + 60 * 60,
'userId' => $tmpUserId,
], '8dc2d81404c4ca0ba23b85b941696534');
$payload = JWT::decode($token, '8dc2d81404c4ca0ba23b85b941696534', ['HS256']);
$user = new User((new Database())->connect());
$result = $user->fetchUserById($payload->userId);
$result = $result->fetchAll(\PDO::FETCH_ASSOC);
if ($result) {
$articleModel = new Article((new Database())->connect());
$isDeleted = $articleModel->delete($tmpArticleId);
$this->assertTrue($isDeleted);
}
}
}
پیش از تفسیر کدهای فوق، ابتدا با استفاده از کامند vendor/bin/phpunit/.
یک بار یونیت تست را اجرا میکنیم:
/var/www/rest-api-blog$ ./vendor/bin/phpunit
PHPUnit 8.1.5 by Sebastian Bergmann and contributors.
Runtime: PHP 7.3.5-1+ubuntu18.04.1+deb.sury.org+1
Configuration: /var/www/rest-api-blog/phpunit.xml
....... 7 / 7 (100%)
Time: 134 ms, Memory: 4.00 MB
OK (7 tests, 7 assertions)
پیش از این داخل کلاس UserControllerTest
دو تست نوشته بودیم و در کلاس جدید DefaultControllerTest
نیز پنج تست مختلف نوشتهایم که جمعاً میشود هفت تست و خروجی نیز حاکی از آن است که هفت یونیت تست با موفقیت انجام شدهاند.
در فانکشن ()testGettingAnArticleById
قابلیت فِچ کردن یک مقاله بر اساس شناسه را تست کردهایم و Assertion مورد استفاده نیز فانکشنی داخل فریمورک PHPUnit تحت عنوان ()assertIsArray
است که چناچه پارامتر ورودیاش یک آرایه باشد، تست را پاس میکند و از آنجا که متغیر result$
یک آرایه میباشد، این تست به درستی پاس خواهد شد. فانکشن ()testGettingAllArticles
نیز قابلیت فراخوانی تمام مقالات را تست میکند و تا حد بسیاری مشابه تست قبلی است.
در ادامه، تستی نوشتهایم به نام ()testCreatingANewArticle
که قابلیت درج یک مقالهٔ جدید در دیتابیس را تست میکند بدین صورت که داخل آن یک شناسهٔ کاربری که حتماً میباید در جدول users
وجود داشته باشد را داخل متغیری به نام tmpUserId$
ذخیره کرده سپس با استفاده از کلاس JWT
یک توکن اِنکُود نموده و آن را داخل متغیر token$
ذخیره کردهایم و مجدد این توکن را دیکُد کرده و مقدارش را داخل متغیر payload$
ریختهایم. در ادامه یک کوئری به جدول users
زده تا از وجود کاربری با شناسهٔ ۱ اطمینان حاصل کنیم و اگر چنین کاربری وجود داشت، وارد بلوک if
شده و پس از ریختن یکسری دیتای دلخواه داخل آرایهای به نام tmpParams$
، متد ()create
از کلاس Article
را فراخوانی کرده و نتیجهاش را داخل متغیری به نام isInserted$
ریختهایم و در نهایت هم از فانکشن ()assertTrue
استفاده کرده تا true
بودن متغیر isInserted$
را تست کنیم.
در تستی تحت عنوان ()testUpdatingAnArticle
که به منظور آزمودن قابلیت بهروزرسانی مقالات نوشتهایم، ساختار تا حد بسیاری مشابه تست قبلی است با این تفاوت که در آن یک متغیر جدید تحت عنوان tmpArticleId$
ساخته که قرار است شناسهٔ یک مقالهای که پیش از این در دیتابیس به ثبت رسیده را در خود ذخیره سازد؛ سپس از متد ()update
استفاده نموده، پارامترهای مورد نیاز را پاس داده و صحت عملکرد این متد را تست نمودهایم.
در نهایت هم به منظور حذف یک مقاله از جدول articles
، متدی نوشتهایم به نام ()testDeletingAnArticle
که در آن با فراخوانی متد ()delete
از مُدل Article
، سازوکار حذف یک مقاله از دیتابیس را تست نمودهایم.