2012-02-22 22 views
28

php kodumu PHPUnit ile test ederken, herhangi bir yöntemle uğraşmadan bir nesneyi alay etmek için doğru yolu bulmaya çalışıyorum.Herhangi bir yöntemle alay etmeden phpunit'te bir alay oluşturma?

Sorun şu ki, getMockBuilder()->setMethods()'u aramazsam, nesne üzerindeki tüm yöntemler alay edilecek ve test etmek istediğim yöntemi arayamıyorum; ama numaralı telefonu setMethods() numaralı telefondan ararsam, bunun hangi yöntemle alay edileceğini söylemem gerekiyor ama herhangi bir yöntemle dalga geçmek istemiyorum. Ama ben sahtekarı yaratmam gerekiyor, bu yüzden testimdeki kurucuyu aramaktan kaçınabilirim. Birlikte myMethod() test edebilir

class Foobar 
{ 
    public function __construct() 
    { 
     // stuff happens here ... 
    } 

    public function myMethod($s) 
    { 
     // I want to test this 
     return (strlen($s) > 3); 
    } 
} 

: Burada

Testten istediğim bir yöntemin önemsiz bir örnek

$obj = new Foobar(); 
$this->assertTrue($obj->myMethod('abcd')); 

Ama bu bilmiyorum Foobar Kullanıcı yapıcı, çağırır istemek. Bunun yerine ben denemek istiyorum: kendi yöntemleri tüm sonuçlanacaktır setMethods() kullanmadan

$obj = $this->getMockBuilder('Foobar')->disableOriginalConstructor()->getMock(); 
$this->assertTrue($obj->myMethod('abcd')); 

Ama çağıran getMockBuilder() alay ve boş dönen varlık, yani myMethod() benim çağrı test etmek niyetinde kod dokunmadan boş dönecektir.

Benim geçici çözüm şimdiye kadar bu olmuştur:

$obj = $this->getMockBuilder('Foobar')->setMethods(array('none')) 
    ->disableOriginalConstructor()->getMock(); 
$this->assertTrue($obj->myMethod('abcd')); 

Bu yok 'none' adlı bir yöntem alay edecek, ancak PHPUnit umursamıyor. MyMethod() unmocked'ını bırakabilir, böylece onu arayabilirim ve aynı zamanda yapıcıyı devre dışı bırakmama izin verir. Mükemmel! Bunun dışında, hile yapmayan bir yöntem ismini belirtmek zorunda gibi görünüyor - 'none' veya 'blargh' veya 'xyzzy'.

Bunu yapmanın doğru yolu ne olurdu?

cevap

38

Herhangi bir yöntemle karşılaşmamak için null - setMethods() arasında geçiş yapabilirsiniz. Boş bir diziyi geçmek tüm yöntemleri alay edecek. Bu, bulduğunuz yöntemlerin varsayılan değeridir.

Diyor ki, bu ihtiyacın, bu sınıfın tasarımında bir kusura işaret edebileceğini söyleyebilirim. Bu yöntem statik mi yoksa başka bir sınıfa mı taşınmalı? Yöntem tamamen yapılandırılmış bir örnek gerektirmiyorsa, statik yapılabilecek bir yardımcı yöntem olabileceğine dair bir işarettir.

+3

Çok teşekkür ederim! SetMethods (null) istediğim gibi görünüyor; Bu alay edilmek için hiçbir yönteme neden olmaz. Diğer taraftan setMethods (array()), tüm yöntemlerin setMethods() yönteminin kullanılmamasıyla aynı şekilde alay edilmesine neden olur. Bunu hiçbir yerde belgelemedim. "Boş ebeveynler" ile ne demek istiyorsun? –

+0

Ayrıca - Yorumunuz şaşkın. Yukarıda verdiğim önemsiz myMethod() örneğinin yanı sıra, neden bu şekilde test edilmesi gereken bir yöntem, yöntemin başka bir sınıfa taşınması veya statik yapılması gerektiğini hissetmenizi sağlar? –

+0

@BrianKendig - "Parens" olması gereken "ebeveynler" de otomatik düzeltme başarısız. :) Sadece kaynağı kontrol ettim ve varsayılan yok, bu yüzden 'null' kendiniz geçmelisiniz. –

3

Başka hacky ama özlü çözüm alay yöntemlerden biri olarak sihirli yapıcı listelemek için basitçe: Bu benim için çalıştı

$mock = $this->getMock('MyClass', array('__construct')); 
-8

:

$this->getMock($class, array(), array(), '', false); 
+0

Noktası tamamen atlandı – dVaffection

0

Ya da sadece doğrudan getMock() kullanabilirsiniz .

$mock = $this->getMock('MyClass', null, array(), null, false);

+0

getMock() – krazyweb

+0

kullanımdan kaldırıldı. Kabul edilen cevap için oy verdim. – Ryan