ฉันจะทดสอบวิธีที่เป็นรูปธรรมของคลาสนามธรรมด้วย PHPUnit ได้อย่างไร
ฉันคาดหวังว่าฉันจะต้องสร้างวัตถุบางอย่างเป็นส่วนหนึ่งของการทดสอบ แม้ว่าฉันไม่ทราบวิธีปฏิบัติที่ดีที่สุดสำหรับสิ่งนี้หรือถ้า PHPUnit อนุญาตสำหรับสิ่งนี้
ฉันจะทดสอบวิธีที่เป็นรูปธรรมของคลาสนามธรรมด้วย PHPUnit ได้อย่างไร
ฉันคาดหวังว่าฉันจะต้องสร้างวัตถุบางอย่างเป็นส่วนหนึ่งของการทดสอบ แม้ว่าฉันไม่ทราบวิธีปฏิบัติที่ดีที่สุดสำหรับสิ่งนี้หรือถ้า PHPUnit อนุญาตสำหรับสิ่งนี้
คำตอบ:
การทดสอบหน่วยของคลาสนามธรรมไม่จำเป็นต้องหมายถึงการทดสอบอินเตอร์เฟสเนื่องจากคลาสนามธรรมสามารถมีวิธีที่เป็นรูปธรรมและสามารถทดสอบวิธีที่เป็นรูปธรรมนี้ได้
ไม่ใช่เรื่องแปลกเมื่อเขียนโค้ดไลบรารีเพื่อให้มีคลาสพื้นฐานที่คุณคาดว่าจะขยายในเลเยอร์แอปพลิเคชันของคุณ และถ้าคุณต้องการตรวจสอบให้แน่ใจว่ามีการทดสอบรหัสห้องสมุดคุณต้องใช้วิธีการที่เป็นรูปธรรมของคลาสนามธรรม
ส่วนตัวผมใช้ PHPUnit และมันมีชื่อเรียกว่า stubs และ mock objects เพื่อช่วยคุณทดสอบสิ่งต่าง ๆ
ส่งตรงจากคู่มือ PHPUnit :
abstract class AbstractClass
{
public function concreteMethod()
{
return $this->abstractMethod();
}
public abstract function abstractMethod();
}
class AbstractClassTest extends PHPUnit_Framework_TestCase
{
public function testConcreteMethod()
{
$stub = $this->getMockForAbstractClass('AbstractClass');
$stub->expects($this->any())
->method('abstractMethod')
->will($this->returnValue(TRUE));
$this->assertTrue($stub->concreteMethod());
}
}
วัตถุจำลองให้คุณหลายสิ่ง:
นั่นเป็นคำถามที่ดี ฉันกำลังมองหาสิ่งนี้เช่นกัน
โชคดีที่ PHPUnit แล้วมีgetMockForAbstractClass()
วิธีการสำหรับกรณีนี้เช่น
protected function setUp()
{
$stub = $this->getMockForAbstractClass('Some_Abstract_Class');
$this->_object = $stub;
}
โปรดทราบว่าต้องใช้ PHPUnit> 3.5.4 มีข้อผิดพลาดในรุ่นก่อนหน้า
ในการอัพเกรดเป็นเวอร์ชั่นใหม่ล่าสุด:
sudo pear channel-update pear.phpunit.de
sudo pear upgrade phpunit/PHPUnit
ควรสังเกตว่ามีการเพิ่มการรองรับ PHP 7 สำหรับคลาสที่ไม่ระบุชื่อ สิ่งนี้ทำให้คุณมีช่องทางเพิ่มเติมสำหรับการตั้งค่าการทดสอบสำหรับคลาสนามธรรมซึ่งไม่ขึ้นอยู่กับฟังก์ชันการทำงานเฉพาะของ PHPUnit
class AbstractClassTest extends \PHPUnit_Framework_TestCase
{
/**
* @var AbstractClass
*/
private $testedClass;
public function setUp()
{
$this->testedClass = new class extends AbstractClass {
protected function abstractMethod()
{
// Put a barebones implementation here
}
};
}
// Put your tests here
}
Eran วิธีการของคุณควรใช้งานได้ แต่มันขัดกับแนวโน้มของการเขียนแบบทดสอบก่อนรหัสจริง
สิ่งที่ฉันอยากจะแนะนำคือการเขียนการทดสอบของคุณเกี่ยวกับการทำงานที่ต้องการของคลาสย่อยที่ไม่ใช่นามธรรมของคลาสนามธรรมที่เป็นปัญหาจากนั้นเขียนทั้งคลาสนามธรรมและคลาสย่อยที่ใช้งานและในที่สุดก็รันการทดสอบ
การทดสอบของคุณควรทดสอบวิธีที่กำหนดของคลาสนามธรรม แต่ผ่านคลาสย่อยเสมอ
คำตอบของเนลสันนั้นผิด
คลาสนามธรรมไม่ต้องการวิธีการทั้งหมดเพื่อให้เป็นนามธรรม
วิธีการใช้งานเป็นวิธีที่เราต้องทดสอบ
สิ่งที่คุณสามารถทำได้คือสร้างคลาสสตับปลอมในไฟล์ทดสอบหน่วยขยายคลาสนามธรรมและใช้เฉพาะสิ่งที่ต้องการโดยไม่มีฟังก์ชั่นการใช้งานทั้งหมดและทดสอบสิ่งนั้น
ไชโย
หากคุณไม่ต้องการซับคลาสคลาสนามธรรมเพียงเพื่อทำการทดสอบหน่วยเกี่ยวกับวิธีการที่นำไปใช้ในคลาสนามธรรมแล้วคุณสามารถลองดูว่ากรอบงานของคุณอนุญาตให้คุณจำลองคลาสนามธรรมหรือไม่