pele_mele:stack_exchange:stack_overflow:28071372
Différences
Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentesRévision précédente | |||
pele_mele:stack_exchange:stack_overflow:28071372 [2024/11/23 04:02] – supprimée - modification externe (Date inconnue) 127.0.0.1 | pele_mele:stack_exchange:stack_overflow:28071372 [2024/11/23 04:02] (Version actuelle) – ↷ Nom de la page changé de pele_mele:stack_exchange:stack_overflow:stackoverflow-28071372 à pele_mele:stack_exchange:stack_overflow:28071372 alexis | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
+ | ====== How to test a concrete method calling an abstract method with phpunit ====== | ||
+ | |||
+ | I have an abstract class with concrete method. So I want to test those concrete methods. | ||
+ | |||
+ | Here is my abstract class: | ||
+ | |||
+ | <code php> | ||
+ | abstract class File { | ||
+ | private $debug_filename_pattern = ' | ||
+ | private $filename; | ||
+ | private $filepath; | ||
+ | |||
+ | abstract public function buildFilename(); | ||
+ | |||
+ | public function __construct($debug = false) { | ||
+ | $filename = $this-> | ||
+ | if ($debug) { | ||
+ | $filename = sprintf($this-> | ||
+ | } | ||
+ | $this-> | ||
+ | $this-> | ||
+ | } | ||
+ | |||
+ | private function buildFilepath() { | ||
+ | $this-> | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | I read the section on testing abstract classes in [[https:// | ||
+ | |||
+ | <code php> | ||
+ | final class FileTest extends \PHPUnit_Framework_TestCase { | ||
+ | public function test() { | ||
+ | $stub = $this-> | ||
+ | $stub-> | ||
+ | -> | ||
+ | -> | ||
+ | -> | ||
+ | $this-> | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | But it is not working. My assert always returns that it fails with this error message: | ||
+ | |||
+ | <code diff> | ||
+ | Failed asserting that two strings are equal. | ||
+ | --- Expected | ||
+ | +++ Actual | ||
+ | @@ @@ | ||
+ | -' | ||
+ | +' | ||
+ | </ | ||
+ | |||
+ | I understand that my mock object is instantiated and then I add a mock for '' | ||
+ | |||
+ | Is there a way to mock my abstract method before instantiation? | ||
+ | |||
+ | <WRAP help> | ||
+ | I don't think that you are able to set up your mock the way that you want. The construct method is being called when you '' | ||
+ | |||
+ | Generally, I find that when something becomes difficult to test as in this case it is a sign that there is an issue with the design. I think that the issue you have is that you are doing too much in your constructor in this case. | ||
+ | |||
+ | You are doing all sorts of heavy lifting to determine the filepath on the construct of your object. Why not change it so that it happens when you call '' | ||
+ | |||
+ | <code php> | ||
+ | abstract class File { | ||
+ | private $debug_filename_pattern = ' | ||
+ | private $filename; | ||
+ | private $filepath; | ||
+ | protected $debug; | ||
+ | |||
+ | abstract public function buildFilename(); | ||
+ | |||
+ | public function __construct($debug = false) { | ||
+ | $this-> | ||
+ | } | ||
+ | |||
+ | private function buildFilepath() { | ||
+ | $filename = $this-> | ||
+ | if ($this-> | ||
+ | $filename = sprintf($this-> | ||
+ | } | ||
+ | $this-> | ||
+ | $this-> | ||
+ | } | ||
+ | |||
+ | public function getFilePath() { | ||
+ | if(!this-> | ||
+ | $this-> | ||
+ | } | ||
+ | |||
+ | return $this-> | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Now in your test to make sure that the path gets built only once just add your assertion one more time. | ||
+ | |||
+ | <code php> | ||
+ | final class FileTest extends \PHPUnit_Framework_TestCase { | ||
+ | public function test() { | ||
+ | $stub = $this-> | ||
+ | $stub-> | ||
+ | -> | ||
+ | -> | ||
+ | -> | ||
+ | $this-> | ||
+ | $this-> | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | </ | ||
+ | <WRAP info> | ||
+ | [[https:// | ||
+ | </ | ||