سؤال

أحاول ترحيل مجموعة من الاختبارات من Simpletest إلى Phpunit وكنت أتساءل عما إذا كان هناك ما يعادله Simpletest السخرس الجزئي.

تحديث: لا يبدو لي أن أجد أي شيء في المستندات التي تشير إلى أن هذه الميزة متاحة، لكنها حدثت لي أنه يمكنني فقط استخدام فئة فرعية. هل هذه فكرة جيدة ام سيئة؟

class StuffDoer {
    protected function doesLongRunningThing() {
        sleep(10);
        return "stuff";
    }
    public function doStuff() {
        return $this->doesLongRunningThing();
    }
}
class StuffDoerTest {
    protected function doesLongRunningThing() {
        return "test stuff";
    }
}
class StuffDoerTestCase extends PHPUnit_Framework_TestCase {
    public function testStuffDoer() {
        $sd = new StuffDoerTest();
        $result = $sd->doStuff();
        $this->assertEquals($result, "test stuff");
    }
}
هل كانت مفيدة؟

المحلول

من قراءة الصفحة المرتبطة، يبدو أن Simpletest Special Mock هو وهمية حيث يتم تجاوز بعض الأساليب فقط. إذا كان هذا صحيحا، يتم التعامل مع هذه الوظيفة بواسطة وهمية Phpunit العادية.

داخل PHPUnit_Framework_TestCase, ، يمكنك إنشاء وهمية

$mock = $this->getMock('Class_To_Mock');

مما يخلق مثيل وهمية حيث لا تفعل كل الطرق شيئا وإرجاع NULL. إذا كنت ترغب في تجاوز بعض الأساليب فقط، فإن المعلمة الثانية ل getMock هي مجموعة من الأساليب لتجاوز.

$mock = $this->getMock('Class_To_Mock', array('insert', 'update'));

سوف تخلق مثيل وهمية من Class_To_Mock مع ال insert و update تتم إزالة الوظائف، جاهزة لقيم الإرجاع المراد تحديدها.

هذه المعلومات في مستندات phpunit.

ملحوظة, هذه الإجابة يظهر المزيد من الأمثلة على مستوى التعليمات البرمجية، للحصول على إصدارات Phpunit بدءا من 5.4

نصائح أخرى

PHPUnit_Framework_TestCase::getMock تم إهمالها منذ phpunit 5.4. وبعد يمكننا ان نستخدم setMethods في حين أن.

يمكن استدعاء SetMethods (أساليب الصفيف $) على كائن Builder Mock لتحديد الطرق التي سيتم استبدالها باختبار قابل للتكوين. لا يتم تغيير سلوك الأساليب الأخرى. إذا قمت باستدعاء SetMethods (NULL)، فسيتم استبدال أي طرق.

https://phpunit.de/manual/current/en/test-doubles.html.

$observer = $this->getMockBuilder(Observer::class)
                 ->setMethods(['update'])
                 ->getMock();

لاحظ أن ما سبق getMock يكون PHPUnit_Framework_MockObject_MockBuilder::getMock. وبعد (phpunit5.6)

لا أعتقد أن phpunit يدعم السخرط الجزئية للنظام قيد الاختبار. إذا كنت تحاول عزل الأساليب، فأنا متأكد من أن تنفيذ أعمالك - لقد فعلت ذلك أيضا.

ومع ذلك، أحاول تجنب القيام بذلك، لبضعة أسباب.

أولا، يتزعم اختبارك بإحكام شديد التنفيذ الداخلي للفئة. هل تهتم حقا ما إذا كانت الطريقة تسمى doesLongRunningThing تم استدعاؤه، أم أنه من الأهم من ذلك أن "Longraunningthing" قد تم؟

ثانيا، عندما أركض هذا الأمر دائما يجعلني أتساءل عما إذا كان لدي فئة واحدة تقوم بعمل اثنين. أ استخراج الفئة قد يكون Refactoring بالترتيب. الاختبار يصبح أسهل بكثير إذا doesLongRunningThing() يصبح صفها الخاص، حتى مع طريقة واحدة.

أعتقد أن الحل هو ضخ الخدمات تعتمد تدقيقك على (http://en.wikipedia.org/wiki/dependency_Injection). هذا يجعل أيضا DoesLongRunningThing التنفيذ أكثر قابلية للتحقق.

دون القفز إلى واجهات، إليك ما سأفعله:

class DoesLongRunningThing {
    public function execute() {
        sleep(10);
        return "stuff";
    }
}

class StuffDoer {
    protected $doesLongRunningThing;

    public function setLongRunningThinger(DoesLongRunningThing $obj) {
        $this->doesLongRunningThing = $obj;
    }

    public function doStuff() {
        return $this->doesLongRunningThing->execute();
    }
}

الآن من السهل أن يسهل وهمية:

class StuffDoerTestCase extends PHPUnit_Framework_TestCase {
    public function testStuffDoer() {
        $dlrtMock = $this->getMock('DoesLongRunningThing');
        $dlrtMock->expects($this->any())->will($this->returnValue("test stuff"));

        $sd = new StuffDoer();
        $sd->setLongRunningThinger($dlrtMock);
        $result = $sd->doStuff();
        $this->assertEquals($result, "test stuff");
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top