حسین طالقانی
حسین طالقانی
خواندن ۱ دقیقه·۵ سال پیش

چرا @dataProvider در PHPUnit کار نمی‌کند؟!

تازه یک تکنیک جدید برای نوشتن تست با PHPUnit یاد گرفته بودم، تکنیکی که خوراک تنبل‌هاست: به جای آن که چندین تست بنویسید، یک تست را چندین بار اجرا کنید!
چطوری؟‌! تست رو به صورت پارامتری می‌نویسین و یک تأمین‌کننده (Data Provider) بهش معرفی می‌کنین که وظیفه‌اش اینه که برای سناریوهای مختلف، پارامترهای ورودی رو تأمین کنه.

به طور معمول شما راهنمای گام به گام رو دنبال می‌کنین و به نتیجه‌ی مطلوب...نمی‌رسه! این بار هم استثناء نبود. در پروژه‌ای که داشتیم، یک تست نوشتم با چند پارامتر ورودی و بعد با استفاده از @dataProvider در DocBlock تابع تأمین‌کننده رو معرفی کردم.

https://gist.github.com/a3dho3yn/c817d69429d2b56a84843d297f43e51e

امّا اجرای تست همان و گرفتن خطا همان:

ArgumentCountError: Too few arguments to function DataProviderTest::testAdd(), 0 passed and at least 3 expected

به نظر می‌رسید اصلاً اهمیتی به تابع معرفی شده نداده! پس سراغ دوستای قدیمی (گوگل و StackOverflow!) رفتم، و مرتبط‌ترین چیزی که دستگیرم شد، این بود که «اگر تابع سازنده (constructor) دارین، یادتون نره داخلش تابع سازنده‌ی parent رو هم صدا بزنین». کلاس تست من تابع سازنده نداشت، کلاس بالاسری‌ش هم که constructor داشت، این شرط رو رعایت کرده بود:

https://gist.github.com/a3dho3yn/cbce7f4367991c385d6a79c253cccc40

پس مشکل کجاست؟

پس از نگاهی به کد و کمک گرفتن از debugger متوجه شدم تابع __construct در PHPUnit\Framework\TestCase چند تا ورودی لازم داره که دریافت نمی‌کنه. تقریباً جواب مشخص شده بود: تابع سازنده‌ی کلاسی که DataProviderTest ازش ارث برده بود، هیچ ورودی‌ای معرفی نکرده بود و به دنبال اون، parent::__construct رو بدون هیچ پارامتری صدا می‌زد. با اضافه کردن این ورودی‌ها، مشکل حل شد:

https://gist.github.com/a3dho3yn/1a2776c08e683975d870f095eb82c320

پانوشت: البته بعد دیدم که در commentهای زیر جواب مورد نظر در StackOverflow کسی همین توضیح را داده بود که متد سازنده، نیاز به ورودی‌هایی دارد.

برنامه نویسیphpphpunittestingتست
سالک .[ ل ِ ] (ع ص ، اِ) مسافر و راه رونده. / a3dho3yn.ir
شاید از این پست‌ها خوشتان بیاید