hielsnoppe
hielsnoppe

Reputation: 2869

Autoload classes for testing from separate directory

Consider the following project layout:

/lib/
    Folders/For/Namespaces/SomeClass.php
/test/
    Folders/For/Namespaces/SomeClassTest.php
composer.json

And this extract from composer.json:

"autoload": {
    "psr-4": {
        "MyNamespace\\" : "lib/"
    }
},
"scripts": {
    "test": "phpunit --bootstrap vendor/autoload.php tests"
}

This allows me to run composer test which will execute SomeClassTest.php among others and \MyNamespace\Folders\For\Namespaces\SomeClass is found by the autoloader.

When building an abstract test case though, I can not get autoloading to work:

/test/
    Folders/For/Namespaces/SomeClassTest.php
    AbstractTest.php

Here \MyNamespace\Folders\For\Namespaces\SomeClassTest extends \MyNamespace\AbstractTest but this is not found by the autoloader. The reason is obvious, because in composer.json the test/ directory is not linked to the namespace. But how can I make this work?

I tried moving \MyNamespace\AbstractTest to \MyNamespace\Test\AbstractTest and adding this namespace to composer.json like this:

"autoload": {
    "psr-4": {
        "MyNamespace\\" : "lib/",
        "MyNamespace\\Test\\" : "test/"
    }
},

But this did not help. What should I do?

Upvotes: 1

Views: 821

Answers (2)

e1v
e1v

Reputation: 637

I might be too late for the answer, but still.

Solution for the problem

Put AbstractTest class into \MyNamespace\Test namespace. That would make it work with your auto-loader configuration:

"autoload": {
    "psr-4": {
        "MyNamespace\\" : "lib/",
        "MyNamespace\\Test\\" : "test/"
    }
},

Development-time auto-loader

Please use autoload-dev section to define development-time auto-loader configuration:

"autoload": {
    "psr-4": {
        "MyNamespace\\" : "lib/",
    }
},
"autoload-dev": {
    "psr-4": {
        "MyNamespace\\Test\\" : "test/"
    }
},

Upvotes: 2

StoryTeller
StoryTeller

Reputation: 1748

If you need some namespaces only for your tests, you can use spl_autoload_register to autoload them manually. See http://php.net/manual/de/function.spl-autoload-register.php

In case of PHPUnit, I you can create a Bootstrap.php in which you can handle your autoloading. This code sample:

spl_autoload_register(function($className) {
    $path = str_replace('\\', '/', $className);
    $testNs = 'MySeparate/Namespace';
    $testNsLength = strlen($testNs);
    if(substr($path, 0, $testNsLength) == $testNs) {
        include_once '/path/to/src/'.$path.'.php';
    }
});

would implement a psr-4 autoloading of a separate namespace.

Upvotes: 1

Related Questions