2013-02-27 14 views
10

Mam problem z kpieniem z przeładowanej metody __get ($ index). Kod dla klasy być wyśmiewany, a system na podstawie testu, który zużywa się następująco:PHPUnit: Mocking __get() powoduje, że "__get() musi przyjmować dokładnie 1 argument ..."

<?php 
class ToBeMocked 
{ 
    protected $vars = array(); 

    public function __get($index) 
    { 
     if (isset($this->vars[$index])) { 
      return $this->vars[$index]; 
     } else { 
      return NULL; 
     } 
    } 
} 

class SUTclass 
{ 
    protected $mocky; 

    public function __construct(ToBeMocked $mocky) 
    { 
     $this->mocky = $mocky; 
    } 

    public function getSnack() 
    { 
     return $this->mocky->snack; 
    } 
} 

testowy wygląda następująco:

<?php  
class GetSnackTest extends PHPUnit_Framework_TestCase 
{ 
    protected $stub; 
    protected $sut; 

    public function setUp() 
    { 
     $mock = $this->getMockBuilder('ToBeMocked') 
        ->setMethods(array('__get') 
        ->getMock(); 

     $sut = new SUTclass($mock); 
    } 

    /** 
    * @test 
    */ 
    public function shouldReturnSnickers() 
    { 
     $this->mock->expects($this->once()) 
        ->method('__get') 
        ->will($this->returnValue('snickers'); 

     $this->assertEquals('snickers', $this->sut->getSnack()); 
    } 
} 

Prawdziwe kod jest trochę bardziej skomplikowane, choć niewiele, posiadające "getSnacks()" w swojej klasie nadrzędnej. Ale ten przykład powinien wystarczyć.

Problem pojawia się następujący błąd podczas wykonywania testu z PHPUnit:

Fatal error: Method Mock_ToBeMocked_12345672f::__get() must take exactly 1 argument in /usr/share/php/PHPUnit/Framework/MockObject/Generator.php(231) 

Kiedy debugowanie nawet nie mogę dotrzeć do metody badawczej. Wygląda na to, że łamie się podczas zakładania fałszywego obiektu.

Wszelkie pomysły?

+0

OK, testowałem trochę dalej. Problem wydaje się być na etapie budowy wyśmiewanej klasy. Jeśli utworzę go za pomocą -> setMethods (array ('blabla')), przechodzi on do metod testowych. Jeśli użyję -> setMethods (array ('__ get')) on pęka. – beToiba

+0

Masz rację - problem polega na tym, jak php php generuje makiety - żadna z odpowiedzi poniżej tego nie dotyczy. Otrzymuję ten problem w PHPUnit 4.0 - jakiej wersji używasz? – HorusKol

+0

Próbowałem odtworzyć to z różnymi kombinacjami wersji PHPUnit i jego zależności Mock Object od najnowszej dostępnej wersji (4.8.2 w momencie pisania) z powrotem do PHPUnit 3.5, i nie mogę tego złamać w ten sposób używając mojego środowisko - PHP 5.5 na Ubuntu 12.04.5 LTS. O ile oryginalny plakat nie może rozwinąć się w tej kwestii, pamiętając o kombinacji wersji, z których korzystali, zaleciłbym, aby to pytanie zostało zamknięte. – Benjamin

Odpowiedz

0

można spróbować go returnCallback zamiast returnValue:

$this->mock->expects($this->once()) 
    ->method('__get') 
    ->will($this->returnCallback(array($this, 'callbackMethod'))); 

które następnie wywołać metodę callbackMethod z parametrami __get została wywołana.

Twoja metoda zwrotna mogłaby wyglądać podobnie do tego:

public function callbackMethod() 
{ 
    return 'snickers'; 
} 

Patrz: http://www.phpunit.de/manual/3.5/en/test-doubles.html#test-doubles.stubs.examples.StubTest5.php

+1

Dzięki za podpowiedź, ale to nie wydaje się być problemem. Wygląda na to, że jest w fałszywym punkcie tworzenia. – beToiba

+0

Świetne, dokładnie to, czego potrzebowałem! –

-1

__get() przyjmuje argument, więc trzeba dostarczyć makiety z jednym:

/** 
* @test 
*/ 
public function shouldReturnSnickers() 
{ 
    $this->mock->expects($this->once()) 
       ->method('__get') 
       ->with($this->equalTo('snack')) 
       ->will($this->returnValue('snickers'); 

    $this->assertEquals('snickers', $this->sut->getSnack()); 
} 

Metoda with() ustawia argument dla wyśmiewanej metody w PHPUnit. Więcej informacji można znaleźć w sekcji na temat Test Doubles.

+0

Włączenie wywołania 'with()' jest tym, co spodziewałem się naprawić, ale nie dla mnie (PHPUnit 4.4). Czy * wypróbowałeś * tę odpowiedź, zanim ją podałeś? Zastanawiasz się, czy po prostu nie zwracasz uwagi na dokumenty, czy wiesz, że działa? –

+0

Myślę, że używałem wtedy 3.7. To (lub coś podobnego) działało, ale nie mogę znaleźć tego, o czym mówiłem, kiedy to pisałem. Ale nie, przetestowałem ten kod. – mAAdhaTTah

+0

Pozdrawiam. Muszę robić coś głupiego (jestem trochę początkującym PHP) –

-1

withAnyParameters() metoda może pomóc, to działa popraw:

$this->mock -> expects($this -> once()) 
    -> method('__get') -> withAnyParameters() 
    -> will($this -> returnValue('snikers')); 
0

Look w wyśmiewali magicznej metody __get. Prawdopodobnie nazywasz tam jeszcze jedną metodę __get od innego i nie jest to właściwie wyśmiewany obiekt.