كائنات وهمية في PHPUnit لمحاكاة المكالمات أسلوب ثابت؟

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

  •  19-08-2019
  •  | 
  •  

سؤال

واني اسعى الى اختبار الطبقة التي تدير الوصول إلى البيانات في قاعدة البيانات (كما تعلمون، CRUD، أساسا). مكتبة DB نستخدمه يحدث أن يكون هناك API حيث تحصل على أول كائن الجدول عن طريق مكالمة ثابتة:

function getFoo($id) {
  $MyTableRepresentation = DB_DataObject::factory("mytable");
  $MyTableRepresentation->get($id);
  ... do some stuff
  return $somedata
}

... تحصل على هذه الفكرة.

ونحن نحاول اختبار هذا الأسلوب، ولكن السخرية من الاشياء DataObject بحيث (أ) ونحن لا تحتاج إلى اتصال ديسيبل الفعلي للاختبار، و (ب) ونحن لا تحتاج حتى لتشمل ليب DB_DataObject للاختبار.

ولكن، في PHPUnit لا أستطيع أن يبدو للحصول على $ هذا-> getMock () لتعيين بشكل مناسب حتى مكالمة ثابتة. لدي ...

        $DB_DataObject = $this->getMock('DB_DataObject', array('factory'));

... ولكن الاختبار لا يزال يقول الأسلوب غير معروف "المصنع". وأنا أعلم أنه خلق الكائن، لأنه قبل ان قالت انها لا يمكن أن تجد DB_DataObject. الآن ما في وسعها. ولكن، لا توجد طريقة؟

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

وأود أن أذكر بأنه التحذير من أن فعلت ذلك في SimpleTest منذ فترة (لا يمكن العثور على رمز) وانها عملت بشكل جيد.

وماذا يعطي؟

و[تحديث]

وأنا بدأت لفهم أن لديها ما تفعله مع تتوقع ()

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

المحلول

وأنا أتفق مع كل واحد منكما أنه سيكون من الأفضل عدم استخدام مكالمة ثابتة. ومع ذلك، أعتقد نسيت أن أذكر أن DB_DataObject هي مكتبة طرف ثالث، والدعوة ثابت هو <م> من أفضل الممارسات لاستخدام التعليمات البرمجية الخاصة بهم، وليس لنا. هناك طرق أخرى لاستخدام أهدافها التي تنطوي على بناء الكائن عاد مباشرة. فإنه يترك فقط تلك مرتق تشمل / تتطلب البيانات في أي ملف فئة تستخدم تلك الفئة DB_DO. أن تمتص لأن الاختبارات وكسر (أو فقط لا تكون معزولة) إذا كنت تحاول في الوقت نفسه للسخرية فئة التي تحمل الاسم نفسه في الاختبار - على الأقل أعتقد

نصائح أخرى

وعندما لا تستطيع تغيير المكتبة، تغيير الوصول منه. ريفاكتور جميع المكالمات إلى مصنع DB_DataObject :: () لأسلوب مثيل في التعليمات البرمجية:

function getFoo($id) {
  $MyTableRepresentation = $this->getTable("mytable");
  $MyTableRepresentation->get($id);
  ... do some stuff
  return $somedata
}

function getTable($table) {
  return DB_DataObject::factory($table);
}

والآن يمكنك استخدام همية الجزئي للدرجة التي كنت اختبار ويكون getTable () إرجاع كائن الجدول وهمية.

function testMyTable() {
  $dao = $this->getMock('MyTableDao', array('getMock'));
  $table = $this->getMock('DB_DataObject', ...);
  $dao->expects($this->any())
      ->method('getTable')
      ->with('mytable')
      ->will($this->returnValue($table));
  $table->expects...
  ...test...
}

وهذا هو مثال جيد للتبعية في التعليمات البرمجية - جعلت من المستحيل تصميم لحقن في همية بدلا من الطبقة حقيقية

وبلدي الاقتراح الأول سيكون في محاولة لريفاكتور رمز لاستخدام مثيل بدلا من مكالمة ثابتة.

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

في إعداد الاختبار الخاصة بك:

 public function setUp() {
      $mockDb = new MockDb();
      DB_DataObject::setAdapter($mockDb);
 }

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

هل تتطلب / بما في ذلك ملف فئة DB_DataObject في حالة الاختبار الخاصة بك؟ إذا كانت الطبقة لا وجود لها قبل PHPUnit تحاول أن يسخر الكائن يمكنك الحصول على مثل هذه الأخطاء.

ومع تمديد PHPUnit MockFunction بالإضافة إلى runkit يمكنك أيضا يسخر أساليب ثابتة. كن حذرا، لأنه قرد الترقيع، وبالتالي ينبغي أن تستخدم إلا في الحالات القصوى. لا بديلا الممارسات البرمجة الجيدة.

https://github.com/tcz/phpunit-mockfunction

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top