Kiểm tra các lớp trừu tượng


144

Làm cách nào để kiểm tra các phương thức cụ thể của một lớp trừu tượng với PHPUnit?

Tôi hy vọng rằng tôi phải tạo ra một số loại đối tượng như là một phần của thử nghiệm. Mặc dù vậy, tôi không biết cách thực hành tốt nhất cho việc này hoặc nếu PHPUnit cho phép thực hiện điều này.


10
Có lẽ bạn nên xem xét thay đổi câu trả lời được chấp nhận.
Jacob

Câu trả lời:


240

Kiểm thử đơn vị các lớp trừu tượng không cần thiết có nghĩa là kiểm tra giao diện, vì các lớp trừu tượng có thể có các phương thức cụ thể và phương thức cụ thể này có thể được kiểm tra.

Không có gì lạ khi viết một số mã thư viện để có một lớp cơ sở nhất định mà bạn mong đợi sẽ mở rộng trong lớp ứng dụng của mình. Và nếu bạn muốn chắc chắn rằng mã thư viện đã được kiểm tra, bạn cần phương tiện để UT các phương thức cụ thể của các lớp trừu tượng.

Cá nhân, tôi sử dụng PHPUnit và nó được gọi là các đối tượng sơ khai và giả để giúp bạn thử nghiệm loại điều này.

Trực tiếp từ hướng dẫn 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());
    }
}

Đối tượng giả cung cấp cho bạn một số điều:

  • bạn không cần phải thực hiện cụ thể lớp trừu tượng và thay vào đó có thể thoát khỏi sơ khai
  • bạn có thể gọi các phương thức cụ thể và khẳng định rằng chúng thực hiện chính xác
  • nếu phương thức cụ thể dựa vào phương thức (trừu tượng) chưa thực hiện, bạn có thể bỏ qua giá trị trả về bằng phương thức will () PHPUnit

38

Đó là một câu hỏi hay. Tôi cũng đang tìm kiếm cái này
May mắn thay, PHPUnit đã có getMockForAbstractClass()phương thức cho trường hợp này, vd

protected function setUp()
{
    $stub = $this->getMockForAbstractClass('Some_Abstract_Class');
    $this->_object = $stub;
}

Quan trọng:

Lưu ý rằng điều này đòi hỏi PHPUnit> 3.5.4. Có một lỗi trong các phiên bản trước.

Để nâng cấp lên phiên bản mới nhất:

sudo pear channel-update pear.phpunit.de
sudo pear upgrade phpunit/PHPUnit

Nghe có vẻ thú vị nhưng bạn sẽ được thử nghiệm chống lại giả? Các bài kiểm tra sẽ như thế nào? IE: mở rộng giả trong trường hợp thử nghiệm và thử nghiệm đối với lớp thử nghiệm mở rộng?
stefgosselin

34

Cần lưu ý rằng hỗ trợ PHP 7 cho các lớp ẩn danh đã được thêm vào. Điều này cung cấp cho bạn một con đường bổ sung để thiết lập một bài kiểm tra cho một lớp trừu tượng, một lớp không phụ thuộc vào chức năng cụ thể của 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
}

4
Cảm ơn bạn vì điều này! Sử dụng một lớp ẩn danh trong PHPUnit đã cho tôi rất nhiều sự linh hoạt trong việc tạo các bài kiểm tra khác nhau của mình.
Alice Wonder

1

Eran, phương pháp của bạn sẽ hoạt động, nhưng nó đi ngược lại xu hướng viết bài kiểm tra trước mã thực tế.

Những gì tôi muốn đề xuất là viết các bài kiểm tra của bạn về chức năng mong muốn của một lớp con không trừu tượng của lớp trừu tượng trong câu hỏi, sau đó viết cả lớp trừu tượng và lớp con thực hiện, và cuối cùng chạy thử nghiệm.

Các thử nghiệm của bạn rõ ràng nên kiểm tra các phương thức đã xác định của lớp trừu tượng, nhưng luôn luôn thông qua lớp con.


Tôi tìm thấy như một câu trả lời tùy ý: Bạn có một lớp trừu tượng 'A' có một phương thức 'foo ()' chung. Phương thức 'foo ()' này đang được sử dụng tổng thể cho tất cả các lớp 'B' và 'C', cả hai đều xuất phát từ 'A'. Bạn sẽ chọn lớp nào để kiểm tra 'foo ()'?
dùng3790897

1

Câu trả lời của Nelson là sai.

Các lớp trừu tượng không yêu cầu tất cả các phương thức của chúng là trừu tượng.

Các phương thức thực hiện là những phương pháp chúng ta cần kiểm tra.

Những gì bạn có thể làm là tạo một lớp sơ khai giả trên tệp kiểm tra đơn vị, để nó mở rộng lớp trừu tượng và chỉ thực hiện những gì được yêu cầu mà không có chức năng nào, tất nhiên, và kiểm tra điều đó.

Chúc mừng.


0

Nếu bạn không muốn phân lớp lớp trừu tượng chỉ để thực hiện kiểm tra đơn vị trên các phương thức đã được triển khai trong lớp trừu tượng, bạn có thể thử xem liệu khung của bạn có cho phép bạn mô phỏng các lớp trừu tượng hay không.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.