Quoting PHPUnit' entry about fixtures
PHPUnit supports sharing the setup code. Before a test method is run, a template method called setUp() is invoked. setUp() is where you create the objects against which you will test. Once the test method has finished running, whether it succeeded or failed, another template method called tearDown() is invoked. tearDown() is where you clean up the objects against which you tested.
Which is clear and concise and I still did not get it.
My daily coding show (metaphorical here) was stopped by this code in my test file
protected $mainPath;
protected $controllersPath;
protected $controllerPath;
protected $viewsPath;
protected $viewPath;
protected $scriptsPath;
protected $scriptPath;
protected $minScriptPath;
protected $stylesPath;
protected $stylePath;
protected $minStylePath;
protected function setUp()
{
// a valid path to a valid main file
$this->mainPath = dirname(dirname(__FILE__)) . '/mvc_helpers/TestMain.php';
$this->controllersPath = dirname(dirname(__FILE__)) . '/mvc_helpers/controllers';
$this->controllerPath = dirname(dirname(__FILE__)) . '/mvc_helpers/controllers/FirstController.php';
$this->viewsPath = dirname(dirname(__FILE__)) . '/mvc_helpers/views';
$this->viewPath = dirname(dirname(__FILE__)) . '/mvc_helpers/views/FirstView.php';
$this->scriptsPath = dirname(dirname(__FILE__)) . '/mvc_helpers/scripts';
$this->scriptPath = dirname(dirname(__FILE__)) . '/mvc_helpers/scripts/FirstScript.js';
$this->minScriptPath = dirname(dirname(__FILE__)) . '/mvc_helpers/scripts/FirstScript.min.js';
$this->stylesPath = dirname(dirname(__FILE__)) . '/mvc_helpers/styles';
$this->stylePath = dirname(dirname(__FILE__)) . '/mvc_helpers/styles/FirstStyle.css';
$this->minStylePath = dirname(dirname(__FILE__)) . '/mvc_helpers/styles/FirstStyle.min.css';
}
public function validFilePathsProvider()
{
return array(
array($this->mainPath) ,
array($this->controllersPath) ,
array($this->controllerPath) ,
array($this->viewsPath) ,
array($this->viewPath) ,
array($this->scriptsPath) ,
array($this->scriptPath) ,
array($this->minScriptPath) ,
array($this->stylesPath) ,
array($this->stylePath) ,
array($this->minStylePath)
);
}
/**
* @dataProvider validFilePathsProvider
*/
public function testWillResolveFromStartingPaths($startingPath)
{
$sut = new FilePathResolver($startingPath); // <<<< I will throw errors
$this->assertEquals($startingPath,$sut->path);
$this->assertEquals($this->controllersPath, $sut->getControllersPath());
$this->assertEquals($this->controllerPath, $sut->getControllerPath('First'));
$this->assertEquals($this->viewsPath, $sut->getViewsPath());
$this->assertEquals($this->viewPath, $sut->getViewPath('First'));
$this->assertEquals($this->scriptsPath, $sut->getScriptsPath());
$this->assertEquals($this->scriptPath, $sut->getScriptPath('First'));
$this->assertEquals($this->minScriptPath, $sut->getScriptPath('First', $min = true));
$this->assertEquals($this->stylesPath, $sut->getStylesPath());
$this->assertEquals($this->stylePath, $sut->getStylePath('First'));
$this->assertEquals($this->minStylePath, $sut->getStylePath('First', $min = true));
}
failing all the tests due to the fact that the FilePathsResolver
class will only take strings as an input, namely absolute paths to a file, and, in the above highlighted line, $startingPath
was not.
How is it? My data provider function, validFilePathsProvider
provided null
strings in place of the one I had set in the setUp
method.
I got the invocation order wrong
I thought PHPunit would have called my functions in this order
setUp
validFilePathsProvider
to provide file paths to…testWillResolveFromStartingPaths
where 2 and 3 will loop due to the data providing mechanism PHPUnit comes with.
I was wrong and the actual order is
validFilePathsProvider
setUp
testWillResolveFromStartingPaths
And hence I can well see that my test method got fed with non initialized strings.
SetUp is made to initialize stuff for the test because it really loves just the tests
Hence I’ve moved the setting of the properties in separate function
protected function setValidFilePaths(){
// a valid path to a valid main file
$this->mainPath = dirname(dirname(__FILE__)) . '/mvc_helpers/TestMain.php';
$this->controllersPath = dirname(dirname(__FILE__)) . '/mvc_helpers/controllers';
$this->controllerPath = dirname(dirname(__FILE__)) . '/mvc_helpers/controllers/FirstController.php';
$this->viewsPath = dirname(dirname(__FILE__)) . '/mvc_helpers/views';
$this->viewPath = dirname(dirname(__FILE__)) . '/mvc_helpers/views/FirstView.php';
$this->scriptsPath = dirname(dirname(__FILE__)) . '/mvc_helpers/scripts';
$this->scriptPath = dirname(dirname(__FILE__)) . '/mvc_helpers/scripts/FirstScript.js';
$this->minScriptPath = dirname(dirname(__FILE__)) . '/mvc_helpers/scripts/FirstScript.min.js';
$this->stylesPath = dirname(dirname(__FILE__)) . '/mvc_helpers/styles';
$this->stylePath = dirname(dirname(__FILE__)) . '/mvc_helpers/styles/FirstStyle.css';
$this->minStylePath = dirname(dirname(__FILE__)) . '/mvc_helpers/styles/FirstStyle.min.css';
}
for code re-usability (but I could have moved the code into the data provider method)
public function validFilePathsProvider()
{
$this->setValidFilePaths();
return array(
array($this->mainPath) ,
array($this->controllersPath) ,
array($this->controllerPath) ,
array($this->viewsPath) ,
array($this->viewPath) ,
array($this->scriptsPath) ,
array($this->scriptPath) ,
array($this->minScriptPath) ,
array($this->stylesPath) ,
array($this->stylePath) ,
array($this->minStylePath)
);
}
while the rest of test code remains the same and will not generate errors anymore.
So today’s gotcha! about PHPUnit is that setUp
is the last method to be invoked before the real test method is. And not the first one in the class.