اختبار قيمة الإرجاع من الأسلوب الذي يتسبب خطأ مع PHPUnit
-
22-07-2019 - |
سؤال
هذا السؤال محددة باستخدام PHPUnit.
PHPUnit تلقائيا بتحويل php أخطاء الاستثناءات. هل هناك طريقة لاختبار قيمة العائد من الطريقة التي يحدث أن يؤدي خطأ php (إما المدمج في أخطاء أو المستخدم ولدت الأخطاء عبر trigger_error)?
مثال على كود الاختبار:
function load_file ($file)
{
if (! file_exists($file)) {
trigger_error("file {$file} does not exist", E_USER_WARNING);
return false;
}
return file_get_contents($file);
}
هذا هو نوع من اختبار أريد أن أكتب:
public function testLoadFile ()
{
$this->assertFalse(load_file('/some/non-existent/file'));
}
المشكلة أنا بعد أن تسبب خطأ يسبب لي وحدة اختبار الفشل (كما يجب).ولكن إذا كنت في محاولة للقبض عليه ، أو مجموعة المتوقع استثناء أي رمز بعد الخطأ هو فعل لم ينفذ حتى ليس لدي أي طريقة اختبار قيمة الإرجاع من طريقة.
هذا المثال لا يعمل:
public function testLoadFile ()
{
$this->setExpectedException('Exception');
$result = load_file('/some/non-existent/file');
// code after this point never gets executed
$this->assertFalse($result);
}
أي أفكار كيف يمكن تحقيق ذلك ؟
المحلول
ليس هناك طريقة للقيام بذلك في وحدة واحدة اختبار.فمن الممكن إذا كنت تفريق اختبار قيمة الإرجاع ، الإشعار إلى اثنين من الاختبارات المختلفة.
PHPUnit خطأ معالج يمسك PHP الأخطاء والملاحظات وتحولها إلى الاستثناءات-الذي بالتعريف توقف تنفيذ البرنامج.وظيفة كنت الاختبار لن يعود على الإطلاق.ومع ذلك ، يمكنك تعطيل مؤقتا تحويل الأخطاء إلى الاستثناءات ، حتى في وقت التشغيل.
وربما هذا هو أسهل مع مثال, إذا, هنا ما اختبارين يجب أن تبدو مثل:
public function testLoadFileTriggersErrorWhenFileNotFound()
{
$this->setExpectedException('PHPUnit_Framework_Error_Warning'); // Or whichever exception it is
$result = load_file('/some/non-existent/file');
}
public function testLoadFileRetunsFalseWhenFileNotFound()
{
PHPUnit_Framework_Error_Warning::$enabled = FALSE;
$result = load_file('/some/non-existent/file');
$this->assertFalse($result);
}
هذا أيضا مكافأة إضافية من إجراء اختبارات أكثر وضوحا ، نظافة النفس توثيق.
Re:التعليق: هذا هو السؤال الكبير ، لم يكن لدي أي فكرة حتى لقد أجريت عدة اختبارات.يبدو كما لو أنه سوف لا استعادة الافتراضي/القيمة الأصلية, على الأقل من PHPUnit 3.3.17 (الحالية الإصدار المستقر الآن).
لذلك أنا في الواقع تعديل أعلاه أن تبدو مثل ذلك:
public function testLoadFileRetunsFalseWhenFileNotFound()
{
$warningEnabledOrig = PHPUnit_Framework_Error_Warning::$enabled;
PHPUnit_Framework_Error_Warning::$enabled = false;
$result = load_file('/some/non-existent/file');
$this->assertFalse($result);
PHPUnit_Framework_Error_Warning::$enabled = $warningEnabledOrig;
}
Re:التعليق الثاني:
هذا ليس صحيحا تماما.أنا أبحث في PHPUnit خطأ معالج, ويعمل على النحو التالي:
- إذا كان
E_WARNING
, استخدامPHPUnit_Framework_Error_Warning
استثناء فئة. - إذا كان
E_NOTICE
أوE_STRICT
خطأ, استخدامPHPUnit_Framework_Error_Notice
- آخر استخدام
PHPUnit_Framework_Error
كما الاستثناء الدرجة.
لذا, نعم, أخطاء E_USER_*
لا تحول إلى PHPUnit هو *_Warning أو *_Notice الصف أنها لا تزال تتحول إلى عام PHPUnit_Framework_Error
الاستثناء.
مزيد من الأفكار
في حين أنه يعتمد بالضبط على كيفية استخدام الدالة, ربما التبديل إلى رمي الفعلي استثناء بدلا من التسبب خطأ ، لو كانت لي.نعم ، هذا من شأنه أن يغير المنطق تدفق الطريقة التعليمات البرمجية التي تستخدم طريقة...الآن التنفيذ لا يتوقف عند ذلك لا يمكن قراءة الملف.ولكن هذا متروك لكم أن تقرر ما إذا كان الملف المطلوب غير موجود حقا استثنائية السلوك.أنا أميل إلى استخدام الاستثناءات أكثر من الأخطاء تحذيرات/إشعارات لأنها أسهل في التعامل معها ، واختبار العمل في التطبيق الخاص بك تدفق.عادة ما نحتفظ إشعارات لأشياء مثل انخفضت المكالمات الأسلوب ، إلخ.
نصائح أخرى
استخدام phpunit.xml
ملف التكوين و تعطيل إشعار/إنذار/خطأ استثناء التحويل.المزيد التفاصيل في دليل.انها في الاساس شيء من هذا القبيل:
<phpunit convertErrorsToExceptions="false"
convertNoticesToExceptions="false"
convertWarningsToExceptions="false">
</phpunit>
بدلا من تتوقع عامة "Exception
"ماذا عن أتوقع "PHPUnit_Framework_Error
" ?
شيء من هذا القبيل قد تفعل :
/**
* @expectedException PHPUnit_Framework_Error
*/
public function testFailingInclude()
{
include 'not_existing_file.php';
}
و أفترض أن ذلك قد يكون أيضا كما هو مكتوب :
public function testLoadFile ()
{
$this->setExpectedException('PHPUnit_Framework_Error');
$result = load_file('/some/non-existent/file');
// code after this point never gets executed
$this->assertFalse($result);
}
لمزيد من المعلومات, انظر اختبار الأخطاء PHP
خصوصا أنه يقول (نقلا عن) :
PHPUnit_Framework_Error_Notice
وPHPUnit_Framework_Error_Warning
تمثل PHP إشعارات الإنذار ، على التوالي.
أنظر /usr/share/php/PHPUnit/TextUI/TestRunner.php الملف لدي على نظام أرى هذا (خط 198 وما بعدها) :
if (!$arguments['convertNoticesToExceptions']) {
PHPUnit_Framework_Error_Notice::$enabled = FALSE;
}
if (!$arguments['convertWarningsToExceptions']) {
PHPUnit_Framework_Error_Warning::$enabled = FALSE;
}
لذلك ربما سيكون لديك لتمرير بعض نوع من المعلمة إلى تفعيل هذا السلوك ؟ ولكن يبدو أن تمكين افتراضيا...
في الواقع هناك طريقة لاختبار كل قيمة الإرجاع و الاستثناء طرح (في هذه الحالة خطأ تحويلها من قبل PHPUnit).
عليك فقط أن تفعل ما يلي:
public function testLoadFileTriggersErrorWhenFileNotFound()
{
$this->assertFalse(@load_file('/some/non-existent/file'));
$this->setExpectedException('PHPUnit_Framework_Error_Warning'); // Or whichever exception it is
load_file('/some/non-existent/file');
}
لاحظ لاختبار قيمة الإرجاع لديك لاستخدام الخطأ قمع المشغل على استدعاء دالة (على @
قبل اسم الدالة).هذه الطريقة استثناء سيتم طرح وتنفيذ سوف تستمر.ثم لديك مجموعة المتوقع أن الاستثناء كالعادة لاختبار خطأ.
ما لا تستطيع القيام به هو اختبار استثناءات متعددة داخل وحدة اختبار.