php - How to stub more complicated methods in PHPUnit -
i'm trying reduce dependencies of program , make more testable. 1 instance did in __construct() method of 1 of classes. before, used take in file name , __construct() method use file_get_contents() on filename save contents property:
public function __construct($name){ $this->name = $name; $this->contents = file_get_contents($name); } to reduce dependency on filesystem replaced with:
public function __construct(splfileobject $file){ $this->name = $file->getfilename(); $this->contents = ''; while(!$file->eof()){ $this->contents .= $file->fgets(); } } i believe more testable, since can mock splfileobject (which set contain whatever content want) , pass in. examples have seen far involve doing this:
$stub = $this->getmock('splfileobject'); $stub->expects($this->any()) ->method('fgets') ->will($this->returnvalue('contents of file')); however mock fgets method of splfileobject need more complicated - needs loop through each line of contents, , stop when has reached end.
for time being have solution works - created entirely new class called mocksplfileobject overrides these methods:
class mocksplfileobject extends splfileobject{ public $maxlines; public $filename; public $contents; public $currentline = 1; public function __construct($filename, $contents){ $this->filename = $filename; $this->contents = explode("\n",$contents); return true; } public function eof(){ if($this->currentline == count($this->contents)+1){ return true; } return false; } public function fgets(){ $line = $this->contents[$this->currentline-1]; $this->currentline++; return $line."\n"; } public function getfilename(){ return $this->filename; } } i use instead of calling phpunit's getmock() function. question is: legitimate way of doing things? or there better way of mocking more complex methods?
$fileobject = $this->getmock('splfileobject', [], ['php://memory']); $fileobject ->expects($this->any()) ->method('fgets') ->will($this->onconsecutivecalls('line 1', 'line 2')); $fileobject ->expects($this->exactly(3)) ->method('eof') ->will($this->onconsecutivecalls(false, false, true)); using 'php://memory' argument splfileobject helped me avoid following error surfaces when try mock splfileobject
php fatal error: uncaught exception 'logicexception' message 'the parent constructor not called: object in invalid state'
Comments
Post a Comment