2015-06-16 21 views
5

Próbuję utworzyć mój pierwszy test phpunit i muszę znaleźć metodę na interfejsie IMailer.Wywołanie PHPUnit do niezdefiniowanej metody `Mock_x _ :: method()`

interface IMailer 
{ 
    public function send($to, $from, $cc, $subject, $body); 
    public function sent(); 
} 

    $mailer = $this->getMockBuilder(
     'IMailer', 
     array('send', 'sent'))->getMock(); 

    $mailer->method('send')->willRreturn(0); 

Jednak wciąż otrzymuję

PHP Fatal error: 
    Call to undefined method Mock_Mailer_13fc0a04::method() 
    in ...Test.php on line 16 

a var_dump($mailer); wyników w

class Mock_IMailer_4c3e02a7#215 (1) { 
    private $__phpunit_invocationMocker => 
    NULL 
} 

Praca z daje błąd dito - wydaje się, że wyśmiewali obiekt nie ma żadnego makiety funkcjonalność ...

Używam phpunit 3.7.28 i php 5.5.9, na pudełku ubuntu.

Jak to możliwe? Jak mogę to naprawić?

Odpowiedz

5

Funkcja getMockBuilder akceptuje tylko parametr className jako parametr. Prawidłowy sposób zainicjować swoje makiety metody obiektu byłoby użyć funkcji setMethods (patrz phpunit docs)

$mailer = $this->getMockBuilder('IMailer') 
     ->setMethods(array('send', 'sent')) 
     ->getMock(); 

Dodatkowo prawdopodobnie chcesz mieć jakąś definicję spodziewa się również podczas korzystania z atrapa obiektu:

$mailer->expects($this->any()) 
     ->method('send') 
     ->willReturn(0); 

EDYTOWANIE

Powyższe stwierdzenie jest prawdziwe w przypadku nowszych wersji phpunit. W przypadku phpunitu 3.7.28 użycie pozorowanego obiektu jest nieco inne (tzn. Oczekiwanie wydaje się obowiązkowe, a funkcja Wrócę nie jest jeszcze dostępna). Dla wersji 3.7.28 należy zmodyfikować druga część:

$mailer->expects($this->any()) 
     ->method('send') 
     ->will($this->returnValue(0)); 

Polecam aktualizację do nowszej wersji phpunit jak wydaje się być nieco trudno znaleźć dokumentację do tego znacznie starszych wydaniach.

+0

Dzięki za sprostowanie mojego 'getMockBuilder' inwokację. Jednak "niezdefiniowana metoda" pozostaje ... – xtofl

+0

Powyższy kod działa ładnie bez błędów na phpunit 4.1.0.Czy próbowałeś dodać wywołanie funkcji expos do drugiej części ('$ mailer-> expect-> method-> willReturn')? Czy możesz udostępnić całą klasę testową, z której korzystasz? To może dać więcej wskazówek do problemu, przed którym stoisz ... – ejuhjav

+1

Myślę, że to powinna być akceptowana odpowiedź. -> setMethods i -> returnValue rozwiązały mój bardzo podobny problem (wydaje mi się, że mam też stare phpunit) – Jimmmy

0

Alternatywnym rozwiązaniem dla każdego, kto nadal używa starych wersji PHPUnit, ale nadal chce mieć możliwość wywoływania bezpośrednio, jest nadpisanie domyślnego szablonu klasy obiektów.

Skopiuj MockObject/Generator/mocked_class.tpl.dist i podaj nazwę kopii mocked_class.tpl. Następnie wystarczy dodać the code for the method() method do szablonu:

public function method() 
{ 
    $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount; 
    $expects = $this->expects($any); 
    $args = func_get_args(); 
    return call_user_func_array(array($expects, 'method'), $args); 
} 

To pozwoli Ci zadzwonić $mock->method() bezpośrednio. Jednak musisz nadal używać ->will($this->returnValue(0)) zamiast ->willReturn(0). Aby to zrobić, trzeba wprowadzić zwyczaj wywołanie konstruktora i wywołania mocker:

class My_MockObject_Builder_InvocationMocker 
    extends PHPUnit_Framework_MockObject_Builder_InvocationMocker { 

    public function willReturn($value) { 
     return $this->will(new PHPUnit_Framework_MockObject_Stub_Return($value)); 
    } 
} 

class My_MockObject_InvocationMocker 
    extends PHPUnit_Framework_MockObject_InvocationMocker { 

    public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher) { 
     return new My_MockObject_Builder_InvocationMocker($this, $matcher); 
    } 
} 

i zaktualizować szablon jeszcze raz, aby korzystać My_MockObject_InvocationMocker zamiast PHPUnit_Framework_MockObject_InvocationMocker.

Pełne szablon będzie wtedy wyglądać tak:

{prologue}{class_declaration} 
{ 
    protected static $staticInvocationMocker; 
    protected $invocationMocker; 

{clone}{mocked_methods} 
    public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher) 
    { 
     return $this->__phpunit_getInvocationMocker()->expects($matcher); 
    } 

    public function method() 
    { 
     $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount; 
     $expects = $this->expects($any); 
     $args = func_get_args(); 
     return call_user_func_array(array($expects, 'method'), $args); 
    } 

    public static function staticExpects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher) 
    { 
     return self::__phpunit_getStaticInvocationMocker()->expects($matcher); 
    } 

    public function __phpunit_getInvocationMocker() 
    { 
     if ($this->invocationMocker === NULL) { 
      $this->invocationMocker = new My_MockObject_InvocationMocker; 
     } 

     return $this->invocationMocker; 
    } 

    public static function __phpunit_getStaticInvocationMocker() 
    { 
     if (self::$staticInvocationMocker === NULL) { 
      self::$staticInvocationMocker = new My_MockObject_InvocationMocker; 
     } 

     return self::$staticInvocationMocker; 
    } 

    public function __phpunit_hasMatchers() 
    { 
     return self::__phpunit_getStaticInvocationMocker()->hasMatchers() || 
       $this->__phpunit_getInvocationMocker()->hasMatchers(); 
    } 

    public function __phpunit_verify() 
    { 
     self::__phpunit_getStaticInvocationMocker()->verify(); 
     $this->__phpunit_getInvocationMocker()->verify(); 
    } 

    public function __phpunit_cleanup() 
    { 
     self::$staticInvocationMocker = NULL; 
     $this->invocationMocker  = NULL; 
    } 
}{epilogue} 
Powiązane problemy