Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHPUnit - autoload classes within tests

Tags:

I have the following structure within my project:

/
/app
/app/models/ --UserTable.php

/lib
/lib/framework
/lib/framework/Models
/lib/framework/Db

/tests -- phpunit.xml, bootstrap.php
/tests/app
/tests/app/models --UserTableTest.php

With the app and lib directories I have various classes that work together to run my app. To setup my tests I have create a /tests/phpunit.xml file and a /tests/bootstrap.php

phpunit.xml

<phpunit bootstrap="bootstrap.php">
</phpunit>

bootstrap.php

<?php

function class_auto_loader($className)
{
  $parts = explode('\\', $className);
  $path = '/var/www/phpdev/' . implode('/', $parts) . '.php';

  require_once $path;
}

spl_autoload_register('class_auto_loader');

So I have the following test:

<?php

class UserTableTest extends PHPUnit_Framework_TestCase
{
  protected $_userTable;

  public function setup()
  {
    $this->_userTable = new app\models\UserTable;
  }

  public function testFindRowByPrimaryKey()
  {
    $user = $this->_userTable->find(1);

    $this->assertEquals($user->id, 1);
  }
}

But it can't find the class when I run the test - PHP Fatal error: Class 'app\models\UserTable' not found in /var/www/phpdev/tests/app/models/UserTableTest.php on line 13

What am I doing wrong? I'm trying to understand PHPUnit configuration better so I opted to write the configuration and bootstrap file myself.

like image 212
Martyn Avatar asked Aug 09 '14 14:08

Martyn


People also ask

What is the PHPUnit XML configuration file used to organize tests?

The <testsuite> Element.

What is autoload class in PHP?

The spl_autoload_register() function registers any number of autoloaders, enabling for classes and interfaces to be automatically loaded if they are currently not defined. By registering autoloaders, PHP is given a last chance to load the class or interface before it fails with an error.

How do I run all PHPUnit tests?

How to Run Tests in PHPUnit. You can run all the tests in a directory using the PHPUnit binary installed in your vendor folder. You can also run a single test by providing the path to the test file. You use the --verbose flag to get more information on the test status.

How do I run a single PHPUnit test?

To Run a single PHPUnit Test Case on a method within the file: Open your PHPUnit Test Case file in the editor. Place your cursor on the method you wish to test, right-click and select Run As | PHP Unit Test.


2 Answers

If you are using composer autoload

change

<phpunit colors="true" strict="true" bootstrap="vendor/autoload.php">

to

<phpunit colors="true" strict="true" bootstrap="tests/autoload.php">

and in tests directory create new autoload.php with following content

include_once __DIR__.'/../vendor/autoload.php';

$classLoader = new \Composer\Autoload\ClassLoader();
$classLoader->addPsr4("Your\\Test\\Namespace\\Here\\", __DIR__, true);
$classLoader->register();
like image 73
Raaghu Avatar answered Oct 03 '22 13:10

Raaghu


You probably should use composer to organize your code, for example, the composer.json in your project root directory should contains something like:

  ...
  "autoload": {
    "psr-0": {
      "PRJ_NAME\\APP\\": "app/",
      "PRJ_NAME\\LIB\\": "lib/"
    }
  },
  ...

Then after run composer update, the two namespaces defined above are put into the vendor/composer/autoload_namespaces.php. Next is simple, just run phpunit with the autoload option like this:

phpunit --bootstrap vendor/autoload.php tests/app/models/UserTableTest

Make sure change the usage of your namespace in both your source code and test code.

like image 45
ImLeo Avatar answered Oct 03 '22 14:10

ImLeo