كيف يمكنك أن تفعل اختبار وحدة مع التطبيق الذي يستخدم ORM؟

StackOverflow https://stackoverflow.com/questions/673518

سؤال

ولقد بدا من خلال الأسئلة المختلفة على وحدة اختبار ولكن لا يمكن العثور على واحد أن يجيب على هذا السؤال على وجه التحديد.

ولقد حصلت عدة فئات PHP التي تحتوي على المهام التي تبدو مثل هذا:

    static function _setSuspended($Suspended, $UserID)
    {
        try {
            $con = Propel::getConnection();

            $c1 = new Criteria();
            $c1->add(DomainsPeer::USERID,$UserID);

            $update = new Criteria();
            $update->add(DomainsPeer::SUSPENDED,$Suspended);

            BasePeer::doUpdate($c1, $update, $con);

            return true;
        } catch(PropelException $e) {
            return $e->getMessage();
        }
    }

وأنا باستخدام إدفع لي في مكتب إدارة السجلات. لقد قرأت من خلال مواضيع مختلفة اختبار وحدة التي تتحدث عن خلق "تزييف" و "الحانات" وليس ما ولكن لم أكن قادرا على العثور على أي شيء أن يقول على وجه التحديد كيفية اختبار وظيفة مثل أعلاه.

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

وأنا لا أرى وسيلة للقيام بذلك. ما أنا في عداد المفقودين هنا؟

هل كانت مفيدة؟

المحلول

ولقد وجدت أن تسخر من ORM لا تعطيني أي ثقة لأن التكوين ORM لم يحصل اختبار. يكون ORMs أيضا الكثير من العمل في الآثار المسافة التي يمكن أن تعطي الثقة الزائفة مع وحدة الاختبارات. ساخرا من برنامج تشغيل قاعدة البيانات أو توفير بديل في الذاكرة قاعدة بيانات يعطيني الثقة أعلى من ذلك بكثير قانون بلدي هو الصحيح وحوالي صعبة كما تسخر من ORM.

وسكليتي هو عظيم قاعدة بيانات في الذاكرة لاختبار وحدة. انها على PDO دعم قائمة قاعدة البيانات. (PDO هو برنامج تشغيل قاعدة البيانات إدفع 1.3.) إذا كنت لا ترغب في استخدام قاعدة بيانات في الذاكرة، قد تكون قادرة على العثور على وهمية PDO كتبت بالفعل.

نصائح أخرى

وهذا هو الجواب العامة في أنني لست على دراية إدفع على الإطلاق، وفقط إلى حد ما أكثر دراية PHP. الجواب الأساسية هي التي تستخدمها التبعية الحقن. بدلا من الإشارة مباشرة إلى مكتب إدارة السجلات الخاصة بك، يمكنك إنشاء مجمع حوله، ثم حقن المجمع في صفك / وظيفة لاستخدامها في الواقع. لإجراء اختبار للوحدة، ثم تقوم بإنشاء نسخة وهمية أو وهمية من المجمع لا واجهة لمكتب إدارة السجلات ولكن بدلا من ذلك تمكنك من تكوين الاستجابات من المجمع إلى الدعاء منهجك. هذا يسمح لك لعامل خارج ORM عندما وحدة اختبار مهامكم.

وكنت أحاول أن معالجة نفس المشكلة في حين أن بناء PHPUnit المساعد لأن symfony . انتهى بي الأمر أنها تقترب على نحو مماثل ل جانغو إطار اختبار - استخدام قاعدة بيانات منفصلة / الصدد، وتدمير وإعادة بنائه قبل كل اختبار

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

ولقد تم قراءة بلوق Misko Hevery حول اختبار كثيرا في الآونة الأخيرة. ويغطي هذا الوضع. كنت بحاجة إلى استخدام DI (حقن التبعية).

وأنا تكافح نفسي مع هذا قليلا كذلك، وأنا أيضا استخدام إدفع.

لواحد، هل يمكن نقل أسلوب "تعليق" إلى فئة "كائن" بدلا من الأقران. لهذا وظيفة معينة على أي حال، لا تحتاج إلى استخدام أساليب ثابتة لتحقيق ذلك. API الخاصة بك يمكن أن تبدو مثل:

MyObjectPeer::retrieveByPK(1)->suspend();

وهذا من شأنه أن يكون قابلا للاختبار عن طريق وسائل اختبار وحدة طبيعية.

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

وهذا هو exemple من فئة مع الاعتماد الصعبة التي لا يمكن أن تكون وحدة قابلة للاختبار.

ونحن يمكن أن تكون قادرة على اختبار مع اتصال إلى قاعدة بيانات أخرى ولكن بعد ذلك، انها ليست اختبار الوحدة بعد الآن بل اختبار التكامل.

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

والأولى في البداية كنت إنشاء واجهة

interface iQueryFactory
{
    function firstFunction($argument);
    function secondFunction($argument, $argument2);
}

ووQueryFactory مع كل طلب ORM الخاص نحتاج

class QueryFactory implements iQueryFactory
{
    function firstFunction($argument) 
    {
        // ORM thing
    }

    function secondFunction($argument, $argument2)
    {
        // ORM stuff
    }
}

وهناك logique تجارية مع حقن المصنع الاستعلام

class BusinessLogic 
{
    protected $queryFactory;

    function __construct($queryFactoryInjection) 
    {
        $this->queryFactory= $queryFactoryInjection;
    }

    function yourFunctionInYourBusinessLogique($argument, $argument2) 
    {
        // business logique

        try {
            $this->queryFactory->secondFunction($argument, $argument2);
        } catch (\Exception $e) {
            // log
            // return thing
        }

        // return stuff
    }
}

والجزء همية، علما بأنني لا تستخدم إطارا وهمية لبلدي exemple (راجع للشغل يمكنك إنشاء اضع الاستجابة)

class QueryFactoryMock implements iQueryFactory
{
    function firstFunction($argument) 
    {
        if (is_null($argument)) 
        {
            throw new \Exception("");
        } 
        else 
        {
            return "succes";
        }
    }

    function firstFunction($argument, $argument2) 
    { 
        // sutff  
    }
}

وثم أخيرا وحدة الاختبارات الذين اختبار المنطق عملنا مع تنفيذ وهمية

class BusinessLogicTest extends PHPUnit_Framework_TestCase 
{
    public function setUp() 
    {
        require_once "BusinessLogic.php";
    }

    public function testFirstFunction_WhenInsertGoodName() 
    {
        $queryMockup = new QueryFactoryMock();
        $businessLogicObject = new BusinessLogic($queryMockup);
        $response = $businessLogicObject ->firstFunction("fabien");

        $this->assertEquals($response, "succes");
    }

    public function testFirstFunction_WhenInsetNull() 
    {
        $queryMockup = new QueryFactoryMock();
        $businessLogicObject = new BusinessLogic($queryMockup);
        $response = $businessLogicObject->firstFunction(null);

        $this->assertEquals($response, "fail");
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top