2013-02-27 5 views
10

Ich habe ein Problem mit Mocking eine überladene __get ($ index) -Methode. Der Code für die Klasse verspottet und das zu testende System werden, die es verbraucht ist, wie folgt:PHPUnit: Mocking __get() führt zu "__get() muss genau 1 Argument nehmen ..."

<?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; 
    } 
} 

-Test sieht wie folgt aus:

<?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()); 
    } 
} 

Real-Code ein wenig komplexer ist, obwohl nicht viel, "getSnacks()" in seiner Elternklasse zu haben. Aber dieses Beispiel sollte ausreichen.

Problem ist ich folgende Fehlermeldung erhalten, wenn Sie den Test mit PHPUnit Ausführung:

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

Wenn ich mich debuggen nicht einmal die Testmethode erreichen kann. Es scheint, dass es beim Einrichten des Mock-Objekts bricht.

Irgendwelche Ideen?

+0

Okay, ich testete ein bisschen weiter. Problem scheint wirklich am Aufbau der verspotteten Klasse zu liegen. Wenn ich es mit -> setMethods (Array ('blabla')) erstelle, kommt er zu den Testmethoden. Wenn ich -> setMethods (array ('__ get')) verwende, bricht er. – beToiba

+0

Sie haben Recht - das Problem hat etwas damit zu tun, wie PHP-Mock-Objekte den Mock erzeugen - keine der folgenden Antworten adressiert dies. Ich bekomme dieses Problem in PHPUnit 4.0 - welche Version verwenden Sie? – HorusKol

+0

Ich habe versucht, dies mit verschiedenen Kombinationen von PHPUnit und Mock Object Abhängigkeit von der neuesten Version (4.8.2 zum Zeitpunkt des Schreibens) zurück zu PHPUnit 3.5 zu erstellen, und kann es nicht auf diese Weise mit meinem brechen Umgebung - PHP 5.5 auf Ubuntu 12.04.5 LTS. Wenn das Originalposter diese Frage nicht erweitern kann, indem es sich an die Kombination der Versionen erinnert, die es verwendet hat, würde ich empfehlen, diese Frage zu schließen. – Benjamin

Antwort

0

Sie könnten es versuchen, mit returnCallback statt returnValue:

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

, die das Verfahren callbackMethod mit den Parametern dann nennen __get genannt wurde.

Ihr Rückruf-Methode wie folgt aussehen könnte:

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

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

+1

Danke für den Hinweis, aber das scheint nicht das Problem zu sein. Es scheint wirklich an einem Schöpfungspunkt zu liegen. – beToiba

+0

Großartig, genau was ich brauchte! –

-1

__get() ein Argument nimmt, so dass Sie die Mock mit einer zur Verfügung stellen müssen:

/** 
* @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()); 
} 

Die with()-Methode legt das Argument für die Mocked-Methode in PHPUnit fest. Weitere Informationen finden Sie im Abschnitt Test Doubles.

+0

Die Aufnahme des 'with()' Aufrufs ist das, was ich erwartet habe, um dies zu beheben, aber es ist nicht für mich (PHPUnit 4.4). Hast du diese Antwort getestet, bevor du sie gegeben hast? Ich frage mich nur, ob du die Docs einfach aufwühlt oder weißt, dass das funktioniert? –

+0

Ich glaube, ich habe 3,7 zu ​​der Zeit verwendet. Dies (oder etwas Ähnliches) funktionierte, aber ich kann nicht finden, worauf ich Bezug nahm, als ich das schrieb. Aber nein, ich habe diesen Code getestet. – mAAdhaTTah

+0

Prost. Ich muss etwas Dummes tun (bin ein bisschen ein PHP-Neuling) –

-1

withAnyParameters() -Methode können Ihnen helfen, das richtig funktioniert:

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

Blick in der verspottete magischen Methode __get. Wahrscheinlich rufst du dort noch eine __get-Methode von einem anderen und nicht korrekt verspotteten Objekt auf.

Verwandte Themen