2012-06-07 27 views
8

hariç tüm yöntemleri alay ediyorum Bazı bağımlılık alay gerekir bir PHPUnit testi, yazıyorum, ancak daha önce olduğu gibi hala çalışmak için birkaç yöntemlere ihtiyacım var. Yani, ben: o yüzden çalıştırmak için karmaşık kod almak ve yok dışarı alay edilirPHPUnit:

// prepare mock object 
$dep = $this->getMockBuilder('Dependency')->disableOriginalConstructor()->getMock(); 
// mock out some other method that should return fixed value 
$dep->expects($this->any())->method("shouldGetTrue")->will($this->returnValue(true)); 
// run test code, it will use thisOneINeed() and shouldGetTrue() 
$result = $testSubject->runSomeCode($dep); 
$this->assertEquals($expected, $result); 

Her şey yöntemiyle thisOneINeed() dışında gayet:

class Dependency { 
// some stuff not important for the test 
    public function thisOneINeed() { 
    /// complex code 
    } 
// some more stuff 
} 

Yani böyle bir şey yapıyordu düzgün çalışmak için runSomeCode() için koşmak gerekiyor. thisOneINeed()'daki bu kod başka bir yöntem çağırmaz, ancak uygun sınama için gerekli ve sabit değer döndürmez, bu yüzden orada statik returnValue() koyamıyorum. Ve AFAIK PHPunit, "ana arama" yazan returnValue() gibi bir yönteme sahip değildir. returnCallback() var, ancak görebildiğim kadarıyla "ebeveyn sınıfı için bu yöntemi çağır" demenin bir yolu yok.

Ben Dependency tüm yöntemlerin listesini yapmak ondan thisOneINeed kaldırmak ve mock oluştururken setMethods() onu geçmek, ama bu yaklaşımı sevmiyorum olabilir, kludgy görünüyor.

class MockDependency extends Dependency 
{ 
    // do not let the mock kill thisOneINeed function 
    final public function thisOneINeed() 
    { 
     return parent::thisOneINeed(); 
    } 
} 

ve sonra sahte nesneyi oluşturmak için MockDependency kullanın ve bu da çalışır, ancak el alay yapmak zorunda sevmiyorum:

Ben de bu yapabilirdi.

Bunu yapmak için daha iyi bir yol var mı?

cevap

9

Eğer PHPUnit'in sahte oluşturucusunu kullanmak istiyorsanız, tüm yöntemleri bir dizi oluşturarak, ihtiyacınız olanı kaldırarak ve setMethods'a aktarmanız tam olarak yapmanız gereken şeydir.

ReflectionClass'ın bir alt sınıfına ihtiyaç duyduğumda kullanabileceğim bir alt sınıfa sahip olmak için birçok durumda yararlı buldum.

class MyReflectionClass extends ReflectionClass 
{ 
    public function getAllMethodNamesExcept(array $excluded) 
    { 
     $methods = array_diff(
      get_class_methods($this->name), 
      $excluded 
     ); 
     return $methods; 
    } 
} 

Ayrıca, yapmak istediğinizi destekleyen farklı bir alay çerçevesini de kullanabilirsiniz. Örneğin, Phake, bir thenCallParent yöntemine sahiptir. Son zamanlarda Phake'yi kullanmaya başladım çünkü bir yönteme aktarılan parametreleri yakalayabilmem gerekiyordu. İyi belgelenmiş ve denemeye değer.