I am giving composer autoload a try with some phpunit testing classes, and I can't seem to get it to work. When I run phpunit from the command line, I get the following error : "PHP Fatal Error: Class ... not found".
I will give all the structure and file information.
I can, so hopefully someone will spot where I went wrong.
Structure (cut down to relevant files):
composer.json
composer.lock
phpunit.xml
vendor/
tests/
functional/
BaseTestCase.php
HomepageTest.php
composer.json
{
"require": {
"php": ">=5.5.0",
"slim/slim": "^3.1",
"slim/php-view": "^2.0",
"monolog/monolog": "^1.17"
},
"require-dev": {
"phpunit/phpunit": ">=4.8 < 6.0"
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
}
}
phpunit.xml
<?xml version="1.0" encoding="utf-8" ?>
<phpunit colors="true" bootstrap="vendor/autoload.php">
<testsuites>
<testsuite name="Initial tests">
<directory>tests/</directory>
</testsuite>
</testsuites>
</phpunit>
test/functional/BaseTestCase.php
<?php
namespace Tests\Functional;
use Slim\App;
use Slim\Http\Request;
use Slim\Http\Response;
use Slim\Http\Environment;
class BaseTestCase extends \PHPUnit_Framework_TestCase
{
...
test/functional/HomepageTest.php
<?php
namespace Tests\Functional;
class HomepageTest extends BaseTestCase
{
...
I then ran an update to refresh the autoload files
$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Writing lock file
Generating autoload files
I then tried running phpunit and got a class not found error:
$ vendor/bin/phpunit
PHP Fatal error: Class 'Tests\Functional\BaseTestCase' not found in <project-root>/tests/functional/HomepageTest.php on line 6
Just to be thorough I tried refreshing the autoload files another way, just in case:
$ composer dump-autoload
Generating autoload files
sfbagency#sfb1:~/clients/ctest/dev$
I also checked vendor/composer/autoload_psr4.php to make sure the Test reference is being set, and it is.
...
Tests\\' => array($baseDir . '/tests'),
...
I have Googled like crazy, but have no idea where I am going wrong.
Namespace directories are case sensitive. You have to rename the folder to Functional
As said in the PSR-4 documentation:
The subdirectory name MUST match the case of the sub-namespace names.
I had a similar problem but without syntax problem.
As soon as I added a second ClassTest (ModelTwoTest.php below), the Fixtures.php class was autoloaded. If I remove 1 modelTest, only the remaining ModelTest is autoloaded without Fixtures. Weird behavior.
src/
tests/
Models/
ModelOneTest.php
ModelTwoTest.php <---
Fixtures/
Fixtures.php
Related
I am struggling with PHP Namespaces and Auto loading in Laravel 5.4. I actually decided to put the models that I need to use in a definite and named folder as app/Models:
php artisan make:model Models/Customer
I have set Customer model's namespace to namespace Models;
Then, I created a route as follows:
Route::get('customer', function () {
$customer = \App\Models\Cutomer::find(1);
echo $customer;
});
To do auto loading work I opened the composer.json file located in the very root folder of the Laravel project and made the autoload to be as follows:
"autoload": {
"classmap": [
"database",
"app/Models"
],
"psr-4": {
"App\\": "app/",
"App\\Models\\": "App/Models"
}
},
After all of this I checked if my composer is an update version and ran dump-autoload:
composer self-update
composer dump-autoload -o
There is also worth of notice the contents of vendor/composer/autoload_classmap.php:
'App\\Models\\Customer' => $baseDir . '/app/Models/Customer.php',
'App\\Models\\Test\\Test' => $baseDir . '/app/Models/Test.php',
My problem is that whenever I execute the url: http://127.0.0.1:8000/customer I will encounter the following error output:
(1/1) FatalThrowableError
Class 'App\Models\Cutomer' not found
Would you please help me understand where of my work has been incorrect, and how to fix it? Thank you very much in advance.
The namespace in the model should be namespace App\Model; (hence why you call the class as \App\Models\Cutomer)
When you use php artisan make:model Models/Customer it should have set the namespace correctly then.
Also, you don't need to edit your composer.json to do this. Remove the additions you've made to your composer.json file for the autoloading and then run composer dumpautoload from the command line.
Hope this helps!
First, you have an error in your PSR-4 setup.
"App\\Models\\": "App/Models"
This does not map to a valid directory. Secondly, and more importantly, there is no need to autoload a nested namespace of one that is already declared. By autoloading App you will already autoload any nested namespaces as long as they conform to PSR-4 standards i.e namespace as directory name and filename as class name.
Composer setup only needs to be the following:
"psr-4": {
"App\\": "app/"
}
Actually Iam new to PHP. I am running this from a nearly empty folder (actually following along a Lara-casts tutorial: Design a Fluent API with TDD).
My directory structure looks like
src
Expression.php
tests
ExpressionTest.php
vendor
composer.json
composer.lock
Inside composer.json:
{
"require-dev": {
"phpunit/phpunit": "^5.2"
},
"autoload": {
"psr-4": {
"": "src/"
}
}
}
Inside ExpressionTest.php:
class ExpressionTest extends PHPUnit_Framework_TestCase
{
/** #test */
public function it_finds_a_string()
{
$regex = Expression::make()->find('www');
$this->assertRegExp($regex, 'www');
}
}
Inside Expression.php
<?php
class Expression
{
}
I then run composer dump-autoload and run phpunit but I still get:
"Fatal error: Class 'Expression' not found in
C:\Users\nobis\code\testing2\tests\ExpressionTest.php on line 8"
Is there something wrong with my syntax? My understanding of Composer is very basic. Thanks in advance.
PHPUnit does not know about Composer natively, therefore without configuring PHPUnit, it will not know about your autoloader setup.
try running PHPunit with --bootstrap vendor/autoload.php to tell it to load with your autoload file.
If that does not work, check your namespace value in your Composer configuration (i.e. "": "src/" might need to change.)
You need to include the autoloader at the top of your test. It is typically at
require __DIR__ . '/vendor/autoload.php';
You can also add a phpunit.xml file to your tell it where the autoloader is then it will run it before every test:
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/5.2/phpunit.xsd"
bootstrap="/path/to/bootstrap.php"
</phpunit>
I have this structure of a project:
root
-lib
-dir
-file1 (namespace PROJECT\dir\)
-file2
-tests
-dir
-file1Test
-file2Test (namespace PROJECT\tests)
-vendor
Composer.json is as follows:
"require-dev":{
"phpunit/phpunit": "5.0.*"
},
"autoload":{
"psr-4":{
"PROJECT\\": "lib/"
}
}
If I run tests without using classes from lib, everything works well. But (for example) if I have
file1Test.php
use PROJECT\dir\file1;
function void testMethod(){
$var = new file1();}
I get this:
Class PROJECT\dir\file1 not found in full/path/to/file1Test.php
Does anyone know where the problem could be?
You probably need to add phpunit.xml to your root, with following content.
<phpunit bootstrap="vendor/autoload.php">
</phpunit>
This would load all classes loaded by composer.
i've troube with the autoloading of composer as the autoloader can't resolve Doctrine\ORM\Mapping\Table.
For the Unittests i have created doctrine entity classes with typical Annotations:
<?php
namespace OmniSearchTest\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Picture
*
* #ORM\Table(name="picture")
* #ORM\Entity
*/
class Picture
{
and created a new entity manager by using this entities. But im getting The Message:
Doctrine\Common\Annotations\AnnotationException: [Semantical Error] The annotation "#Doctrine\ORM\Mapping\Table" in class OmniSearchTest\Entity\Picture does not exist, or could not be auto-loaded.
For some Unittests
First, i have the following project structure:
/src
/OmniSearch
SomeClass.php
/tests
/OmniSearchTest
SomeClassTest.php
/composer.json
/phpunit.xml.dist
My composer.json looks like this:
{
/* ... */
"require": {
"php": ">=5.4",
"doctrine/orm": "2.*"
},
"require-dev": {
"phpunit/phpunit": "4.*"
},
"autoload": {
"psr-0": {
"OmniSearch\\": "src/"
}
},
"autoload-dev": {
"psr-0": {
"OmniSearchTest\\": "tests/"
}
}
}
While my phpunit looks excactly like this:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
strict="true"
verbose="true">
<testsuites>
<testsuite name="omnisearch">
<directory>./tests/OmniSearchTest</directory>
</testsuite>
</testsuites>
</phpunit>
I cutted off this project from another zf2 project of mine where the autoloading was working fine. Im not sure what exactly went wrong because the autogenerated autoload_namespaces.php contains the the mapping:
'Doctrine\\ORM\\' => array($vendorDir . '/doctrine/orm/lib'),
This is kind of a shot in the dark but Symfony 2 applications include an autoload.php file which explicitly loads an annotation registry.
// autoload.php
use Doctrine\Common\Annotations\AnnotationRegistry;
use Composer\Autoload\ClassLoader;
/**
* #var ClassLoader $loader
*/
$loader = require __DIR__.'/../vendor/autoload.php';
AnnotationRegistry::registerLoader(array($loader, 'loadClass'));
return $loader;
I never really researched why in any detail since I don't use annotations. But give it a try. Can't hurt.
This is a bit old, but I created a composer plugin which registers composer ClassLoader into the AnnotationRegistry as a loader.
https://github.com/indigophp/doctrine-annotation-autoload
First run this command:
composer require indigophp/doctrine-annotation-autoload
After that finishes, run this:
composer dump-autoload
I have a normal directory structure:
- root
- vendor
- bin/phpunit
- tests
- bootstrap.php
my composer.json:
{
"name": "test/testing",
"minimum-stability": "dev",
"require": {
"phpunit/phpunit": "4.1.*#dev",
"phpunit/phpunit-mock-objects": "2.2.*#dev"
},
"autoload": {
"classmap": ["tests/config.inc","test.inc"]
}
}
My bootstrap.php:
<?php
require_once 'vendor/autoload.php';
There is some other stuff inside the bootstrap, thats why I need it,
but I removed it here because it has nothing to do with my problem.
When I try to run PHPUnit at the root folder:
vendor/bin/phpunit --bootstrap tests/bootstrap.php tests/ItemsTest.php
I get the error:
PHP Warning: require(xxxx/vendor/phpunit/phpunit-mock-objects/tests/../vendor/autoload.php): failed to open stream: No such file or directory in xxxxxxx/vendor/phpunit/phpunit-mock-objects/tests/bootstrap.php on line 4
i donĀ“t know why phpunit/the autoloader is loading this bootstrap:
phpunit-mock-objects/tests/bootstrap.php
and of course line 4 in there:
require __DIR__ . '/../vendor/autoload.php';
does not work.
PhpUnit does not understand the bootstrap path as relative for whatever reason.
Replacing the bootstrap path as follows seems to do the trick:
vendor/bin/phpunit --bootstrap ./tests/bootstrap.php tests/ItemsTest.php