تازه یک تکنیک جدید برای نوشتن تست با PHPUnit یاد گرفته بودم، تکنیکی که خوراک تنبلهاست: به جای آن که چندین تست بنویسید، یک تست را چندین بار اجرا کنید!
چطوری؟! تست رو به صورت پارامتری مینویسین و یک تأمینکننده (Data Provider) بهش معرفی میکنین که وظیفهاش اینه که برای سناریوهای مختلف، پارامترهای ورودی رو تأمین کنه.
به طور معمول شما راهنمای گام به گام رو دنبال میکنین و به نتیجهی مطلوب...نمیرسه! این بار هم استثناء نبود. در پروژهای که داشتیم، یک تست نوشتم با چند پارامتر ورودی و بعد با استفاده از @dataProvider در DocBlock تابع تأمینکننده رو معرفی کردم.
امّا اجرای تست همان و گرفتن خطا همان:
ArgumentCountError: Too few arguments to function DataProviderTest::testAdd(), 0 passed and at least 3 expected
به نظر میرسید اصلاً اهمیتی به تابع معرفی شده نداده! پس سراغ دوستای قدیمی (گوگل و StackOverflow!) رفتم، و مرتبطترین چیزی که دستگیرم شد، این بود که «اگر تابع سازنده (constructor) دارین، یادتون نره داخلش تابع سازندهی parent رو هم صدا بزنین». کلاس تست من تابع سازنده نداشت، کلاس بالاسریش هم که constructor داشت، این شرط رو رعایت کرده بود:
پس از نگاهی به کد و کمک گرفتن از debugger متوجه شدم تابع __construct در PHPUnit\Framework\TestCase چند تا ورودی لازم داره که دریافت نمیکنه. تقریباً جواب مشخص شده بود: تابع سازندهی کلاسی که DataProviderTest ازش ارث برده بود، هیچ ورودیای معرفی نکرده بود و به دنبال اون، parent::__construct رو بدون هیچ پارامتری صدا میزد. با اضافه کردن این ورودیها، مشکل حل شد:
پانوشت: البته بعد دیدم که در commentهای زیر جواب مورد نظر در StackOverflow کسی همین توضیح را داده بود که متد سازنده، نیاز به ورودیهایی دارد.