2012-11-14 19 views
9

Sahte nesnenin aksine phpunit ile bir sahte sınıf oluşturmanın bir yolu var mı? Bağımlılık enjeksiyonu yapmanın bir yolunu, bir sınıfın yapıcıda (ya da her yerde) çalışmak için ihtiyaç duyabileceği her nesneyi açıkça geçmek zorunda kalmadan araştırıyorum. Tüm bu durumlarda için "doğru" dönecektir şey:Phpunit ile bir alay sınıfı oluşturun?

public function testAAAA() 
{ 
    $foo = $this->getMock('foo', array('bar')); 
    var_dump(class_exists('foo', false)); 
    var_dump(method_exists('foo', 'bar')); 
    var_dump(method_exists($foo, 'bar')); 
} 

Bu baskılar:

bool(true) 
bool(false) 
bool(true) 

başarıyla sahte 'foo' sınıfı yarattı ederken bir 'bar bağlamak olmadığını belirten 'ona yöntem.

Phpunit 3.7.5 kullanıyorum.

cevap

10

Ben aslında (eğer the docs bkz PHPUnit en mockbuilder ile benzeri kurucular devre dışı bırakmak ve gibi) bunu yapmak istemiyoruz şüpheli ama istediğiniz ya gerek yok varsayarak bu hile yapmak gerekir:

$foo = $this->getMockBuilder('nonexistant') 
     ->setMockClassName('foo') 
     ->setMethods(array('bar')) 
     ->getMock(); 

    var_dump(class_exists('foo', false)); 
    var_dump(method_exists('foo', 'bar')); 
    var_dump(method_exists($foo, 'bar')); 

    $cls = new ReflectionClass('foo'); 
    var_dump($cls->hasMethod('bar')); 

Yukarıdaki farklı adların (neden olmayan ve foo) neden belirtilmesi gerektiğinin ayrıntılarını dürüst bir şekilde bilmiyorum, ancak alay konusu olan sınıf henüz olmadığında PHPUnit'in davranışı ile ilgili olması gerektiği anlaşılıyor. ve setMockClassName sahip olmak, bu sınıfı genişleten bir sınıf oluşturur. Ya da başka birşey. Muhtemelen bir bug/edge-case etrafında çalışmaktadır - bu kütüphanenin garip bir kullanımıdır. Aynı şeyi sadece getMock işlevini kullanarak yapabilmeniz gerekir, sadece çirkin.

Bir kenara göre, muhtemelen php's reflection capabilities ile aşina olmanız gerektiği gibi geliyor. Dışarıdaki en güçlü yansıma kütüphanesi değil, ama oldukça hoş. Bir sınıf için yapıcı argümanlarına ve bir "model" kitaplığı için özelliklerine göre gerekli ve isteğe bağlı alanlar hakkında meta bilgi oluşturmak için kullandım, bu meta bilgi, doğru değerler türlerini kabul eden formları oluşturmak için kullanılır. Yani, formun olduğu sınıfın örnekleri olmadan yazılan formlar üretin ve aptal miktarda kod yazmadan - tüm özellik için yaklaşık 100 satırlık bir sayıdır. Açıkçası, ne yapmaya çalıştığını bilmiyorum, ama yazınındaki küçük bilgi miktarından, bu tür bir meta-şeye daha yakın olduğunu sanırdım.

+0

Bunu yapmak istemediğimi söylemem ama bunu yapmam gerek. Gerçek DI eklemek için on binlerce dosyayı değiştirmeden, testin içinde yapılan çağrılara cevap verecek sahte bir nesne üretebilmem gerekiyor. Bu getMockBuilder yöntemi beni yakınlaştırıyor, ama phpunit adında bir isim sınıfıyla isimlendirildiğinde kötü durum kodu üretiyor gibi görünüyor (orijinal yazılarda belirtmiş olduğum şeyi kullanıyorum). –

+0

'getMock()' çağrısından sonra 'class_alias' 'class_alias' '(' foo ',' quux \ baz ') 'gibi bir çağrı ekleyin ve' quux \ baz 'ile sınayın. Tabii ki, temelde PHPUnit'i ya da ReflectionClass ve ReflectionObject'in bir nesneyi veya sınıfa bir yöntem ekleyebilme yeteneğini kullanabileceğinizi düşündüğünüz noktada ve siz de kenar davalarına vuracaksınız. Bu, PHP'nin parladığı bir alan değil. Ayrıca, eğer okumadıysanız, Michael Feathers'ın “Eskiden Kalıcı Bir Şekilde Çalışma” başlıklı bir kopyasına * ihtiyacınız var. – jeremiahd

+0

Teşekkürler. Class_alias'ı deneyeceğim. Ayrıca, PHPUnit'in yamalarını inceleyerek, bir eval() 'da kullandığı şablonu değiştiriyorum. Kitaba gelince, gerçekten ihtiyacım olan şey, patronların okumasını sağlamak. :) –

İlgili konular