Soyut Sınıfları Test Etme


144

Soyut bir sınıfın somut yöntemlerini PHPUnit ile nasıl test edebilirim?

Testin bir parçası olarak bir tür nesne yaratmamı beklerdim. Yine de, bunun için en iyi uygulama veya PHPUnit buna izin veriyorsa hiçbir fikrim yok.


10
Belki de kabul edilen cevabı değiştirmeyi düşünmelisiniz.
Jacob

1
Belki stackoverflow.com/a/2947823/23963 yardımcı olacaktır.
Nigel Thorne

Yanıtlar:


240

Soyut sınıfların birim testi, soyut sınıfların somut yöntemlere sahip olabileceği ve bu somut yöntemlerin test edilebileceği için arayüzü test etmek anlamına gelmez.

Bazı kütüphane kodlarını yazarken, uygulama katmanınızda genişletmeyi beklediğiniz bazı temel sınıflara sahip olmak çok nadir değildir. Ve eğer kütüphane kodunun test edildiğinden emin olmak istiyorsanız, soyut sınıfların somut yöntemlerini UT'ye getirmeniz gerekir.

Şahsen, PHPUnit kullanıyorum ve bu tür şeyleri test etmenize yardımcı olmak için saplamalar ve sahte nesneler olarak adlandırdı.

Doğrudan PHPUnit kılavuzundan :

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());
    }
}

Sahte nesne size birkaç şey verir:

  • soyut sınıfın somut uygulamasına sahip olmanız gerekmez ve bunun yerine saplamadan kurtulabilirsiniz
  • somut yöntemler çağırabilir ve doğru performans gösterdiklerini iddia edebilirsiniz
  • somut yöntem uygulanmamış (soyut) yönteme dayanıyorsa, dönüş değerini will () PHPUnit yöntemiyle saplayabilirsiniz

38

Bu iyi bir soru. Ben de bunu arıyordum.
Neyse ki, PHPUnit'in getMockForAbstractClass()bu durum için zaten bir yöntemi var, örn.

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

Önemli:

Bunun PHPUnit> 3.5.4 sürümünü gerektirdiğini unutmayın. Önceki sürümlerde bir hata oluştu .

En yeni sürüme geçmek için:

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

Kulağa ilginç geliyor ama alaya karşı test mi edeceksin? Testler nasıl olurdu? IE: test durumunda sahte genişletme ve genişletilmiş test sınıfına karşı test?
stefgosselin

34

PHP 7'den itibaren anonim sınıflar için destek eklendiğine dikkat edilmelidir . Bu, PHPUnit'e özgü işlevselliğe bağlı olmayan soyut bir sınıf için bir test ayarlamak için ek bir yol sağlar.

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
Bunun için teşekkürler! PHPUnit'te anonim bir sınıf kullanmak, çeşitli testlerimi oluşturmada bana çok fazla esneklik kazandırdı.
Alice Wonder

1

Eran, yönteminizin çalışması gerekir, ancak gerçek koddan önce testi yazma eğilimine karşı gelir.

Önereceğim şey, testlerinizi söz konusu soyut sınıfın soyut olmayan bir alt sınıfının istenen işlevselliği üzerine yazmak, ardından hem soyut sınıfı hem de uygulayan alt sınıfı yazmak ve sonunda testi çalıştırmaktır.

Testleriniz, soyut sınıfın tanımlı yöntemlerini açık bir şekilde test etmelidir, ancak her zaman alt sınıf aracılığıyla.


Ben keyfi bir cevap olarak buluyorum: Ortak bir 'foo ()' yöntemine sahip soyut bir 'A' sınıfı var. Bu 'foo ()' yöntemi genel olarak tüm 'B' ve 'C' sınıflarında kullanılmaktadır, her ikisi de 'A'dan türetilmiştir. Hangi sınıfı 'foo ()' test etmek istersiniz?
user3790897

1

Nelson'ın cevabı yanlış.

Soyut sınıflar, tüm yöntemlerinin soyut olmasını gerektirmez.

Uygulanan yöntemler test etmemiz gereken yöntemlerdir.

Yapabileceğiniz şey, birim test dosyasında sahte bir saplama sınıfı oluşturmak, soyut sınıfı genişletmesini sağlamak ve yalnızca hiçbir işlevsellik olmadan gerekli olanları uygulamak ve elbette bunu test etmektir.

Şerefe.


0

Yalnızca soyut sınıfta uygulanan yöntemler üzerinde bir birim sınama yapmak için soyut sınıfı alt sınıflara ayırmak istemiyorsanız, çerçevenizin soyut sınıflarla alay etmenize izin verip vermediğini görmeye çalışabilirsiniz .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.