I am learning TDD and I want to test my AutoLoader class, what needs to do the next job:
- do a check is the namespace is string
- do a check, is the path to directory parameter is a string
- do a check is the path to directory what I want to load is exists, directory and readable.
There will be more jobs, but I am newbee, so I need your opinion about my test:
<?php
namespace Myframework\Application\Autoloader;
class Autoloader {
/**
* @var string
*/
protected $namespace;
/**
* @var string
*/
protected $path;
public function __construct($namespace, $pathToClassesDirectory = '') {
if (!is_string($namespace)) {
throw new \Exception('Namespace must be string');
}
if (!is_string($pathToClassesDirectory)) {
throw new \Exception('Path to directory parameter should be string');
}
if (!file_exists($pathToClassesDirectory) || !is_dir($pathToClassesDirectory) || !is_readable($pathToClassesDirectory)) {
throw new \Exception('Path to directory is not accessible to read: "' . $pathToClassesDirectory . '"');
}
$this->namespace = $namespace;
$this->path = $pathToClassesDirectory;
}
}
The class:
<?php
use PHPUnit\Framework\TestCase;
/**
* @author vaso
*/
require_once '../system/Application/Autoloader/Autoloader.php';
class AutoloaderTest extends TestCase {
protected $Autoloader;
public function setUp() {
$this->Autoloader = new Myframework\Application\Autoloader\Autoloader(TEST_NAMESPACE, BASE_PATH);
}
public function tearDown() {
unset($this->Autoloader);
}
public function testConstructorCall() {
new Myframework\Application\Autoloader\Autoloader('nameSpaceAsString', BASE_PATH);
}
public function testConstructorCallNameSpaceIsNotStringException() {
$this->expectException('Exception');
new Myframework\Application\Autoloader\Autoloader(2);
}
public function testConstructorCallPathIsNotStringException() {
$this->expectException('Exception');
$notStringForPath = new stdClass();
new Myframework\Application\Autoloader\Autoloader(TEST_NAMESPACE, $notStringForPath);
}
public function testIsDirectoryExistsException() {
$this->expectException('Exception');
new Myframework\Application\Autoloader\Autoloader('x', 'Failed directory what not exist');
}
}
Test passed, and my methods are works, I am happy. But I doubt this is not how TDD works even if I follow every requirements.
My questions are:
- Is it ok to use constants in test what comes from
bootstrap.php
to define path? - All of the test ok, but is this the right way to test a constructor? I feel no for some reason, if its ok, please tell me, if not, please tell me why.
I found a lot of resources about TDD, videos, books, but testing the constructor is not in it.
-
\$\begingroup\$ Not sure I am following. Where does loading actually happen? Also, I would think that in this day and age, if one were to build an autoloader, they would do son in PSR-4 compliant fashion. See PSR-4 examples implementations here: github.com/php-fig/fig-standards/blob/master/accepted/… I guess I don't understand the need to "roll your own" autoloader at this point when this is territory that is very well covered in PHP. \$\endgroup\$Mike Brant– Mike Brant2017年03月06日 22:43:16 +00:00Commented Mar 6, 2017 at 22:43
-
\$\begingroup\$ Load is not implemented yet, and I am loading as PSR suggested in other projects. That is a unit, what I can test by unit test. Yes, I am know unit test is for units, but if I want to be sure that my code is coveraged I should write tests for the constructor too. \$\endgroup\$vaso123– vaso1232017年03月07日 08:55:53 +00:00Commented Mar 7, 2017 at 8:55
1 Answer 1
After some research, I've got these answers:
Testing constructor is totally unnecessary if you follow this: Constructor does Real Work. Unit test for units. The constructor only job is to build the object, nothing else, no new objects creation, no initializing, etc...
For constants: I see no reason why do not use constants (for example for a path) to help me to access my classes for tests.