عمليات CRUD بالبرمجة الموجهة للإختبار - اختبار عملية اﻹنشاء Create

Laravel PHP CRUD TDD

في المقالة السابقة قمت بالكتابة عن كيفية اختبار عمليات CRUD وبدأت أولا بعملية الإضافة create وقمنا باختبار أنه يمكن إضافة مهمة Task بنجاح، ولكننا لم نقم باختبار اﻹحتمالات أخرى للتأكد من:

  • لا يمكن للأشخاص الغير مسجلين دخولهم إضافة مهمة جديدة
  • رسائل أخطاء التحقق على الحقول ترجع بطريقة صحيحة

    لا يمكن للأشخاص الغير مسجلين دخولهم إضافة مهمة جديدة:

لنبدأ بكتابة دوال الاختبار لهذه الحالات، ولنبدأ أولا بالتأكد من أنه لا يمكن للأشخاص الغير مسجلين دخولهم إضافة مهام جديدة، عن طريق دالة الاختبار التالية

       /**
*@test
*/

function unauthenticated_user_can_not_create_new_task()
{
$this->post('/tasks', [
'title' => $title = 'write a blog post',
'description' => $description = 'write a post about CRUD operations using TDD',
])
->assertRedirect('/login');

$this->assertDatabaseMissing('tasks', [
'title' => $title,
'description' => $description,
]);
}



نلاحظ أنه في هذا الاختبار لم نقم بإضافة مستخدم وتسجيل دخوله، وذلك لمحاكاة أن الشخص حالياً هو guest، ثم قمنا بالتأكد من أنه سيتم إعادة توجيهه إلى صفحة login/ وتأكدنا أنه لم يتم إضافة هذه المهمة لقاعدة البيانات، ولنقوم بتنفيذ الاختبار عن طريق تنفيذ الأمر

    ./vendor/bin/phpunit unauthenticated_user_can_not_create_new_task



نلاحظ أن كود الخطأ الموضح هو 500 (server error) بدون رسالة توضح ماهو مصدر الخطأ وأين؟ كما أوضحت في المقالة السابقة يمكننا إرجاع رسائل اﻷخطاء Exception Messages بدوال الاختبار عن طريق إلغاء تفعيل Exceptions Handling كالتالي:

    /**
*@test
*/

function unauthenticated_user_can_not_create_new_task()
{
$this->withoutExceptionHandling();

$this->post('/tasks', [
'title' => $title = 'write a blog post',
'description' => $description = 'write a post about CRUD operations using TDD',
])
->assertRedirect('/login');

$this->assertDatabaseMissing('tasks', [
'title' => $title,
'description' => $description,
]);
}

وعند تنفيذ الاختبار مرة أخرى



الخطأ يوضح أنه عند إضافة مهمة جديدة وتخزين المستخدم المسجل دخوله لإضافتها له يحدث الخطأ وذلك لأنه لا يوجد مستخدم مسجل دخوله، فلهذا لحل هذه المشكلة نقوم بحماية هذا route ليكون للمستخدمين المسجلين دخولهم فقط، عن طريق استخدام Auth Middleware.

في حال كانت نسخة Laravel 6+ يجب تثبيت حزمة laravel/ui

composer require laravel/ui

وتنفيذ اﻷمر التالي لإضافة Auth Scaffolding

php artisan ui vue --auth

ونقوم بإضافة Auth middleware إلى route إضافة مهمة، كالتالي:

Route::post('/tasks', 'TaskController@store')->middleware('auth');

حيث أن هذا middleware هو المسؤول عن التأكد من أنه يجب أن يكون هناك مستخدم مسجل دخوله ليتمكن من إستخدام route هذا، وفي حال لم يكن هناك مستخدم مسجل، يقوم بإعادة توجيهه إلى صفحة تسجيل الدخول login/ ، نقوم بإعادة تنفيذ الاختبار ونرى النتيجة



نرى أن الرسالة توضح أنه المستخدم غير مسجل دخوله Unauthenticated وهذه هي الرسالة المطلوبة ولكن نحن نريد التأكد من أنه يتم إعادة توجيهه إلى صفحة login بدلا من معرفة الرسالة ولهذا يمكننا الآن إلغاء $this->withoutExceptionHandling(); وإعادة تنفيذ الاختبار.



التأكد من أن رسائل اﻷخطاء التحقق على الحقول ترجع بطريقة صحيحة

كتابة الاختبار للتحقق من أن رسائل أخطاء التحقق المحددة على الحقول ترجع بطريقة صحيحة، حسب قواعد التحقق التي اضفناها على الحقول:

    request()->validate([
'title' => 'required|string',
'description' => 'required'
]);

وتكون دالة الاختبار كالتالي:

    /**
*@test
*/

function it_returns_proper_validation_errors_when_creating_new_task()
{
$user = factory('App\User')->create();

$this->actingAs($user);

$this->post('/tasks', [
'title' => '',
'description' => '',
])
->assertSessionHasErrors(['title', 'description']);
}

قمنا بهذه الدالة بإنشاء مستخدم جديد وتسجيل دخوله، تم إرسالنا طلب Request إنشاء مهمة جديدة بحقلي العنوان والتفاصيل (title, description) فارغات، وأردنا أن نتأكد من أن الجلسة session تحتوي على رسائل أخطاء التحقق لكل من الحقلين title, description

عند تنفيذ الاختبار:



ولأننا قمنا بتحديد هذين الحقلين كحقول مطلوبة required فعند إرسال طلب بدون تعبئتها نرى أنهم سيتم إضافة رسائل أخطاء التحقق الخاصة بهذين الحقلين للجلسة Session ليتم عرضهم بالواجهة على Form Inputs. يمكننا بهذا الاختبار التحقق من المزيد من القواعد Validation Rules، عن طريق إرسال حقول ببيانات مخالفة لقواعد التحقق المحددة على الحقول.