24

I'm new to PHPUnit and am having some trouble setting it up to access my PHP files. The directory structure I'm using for my app is this:

./phpunit.xml

./lib/Application/
  -> Dir1/File1.php (namespace = Application\Dir1)
  -> Dir1/File2.php
  -> Dir2/File1.php (namespace = Application\Dir2)

./tests/Application/Tests
  -> Test1.php (namespace = Application\Tests)
  -> Test2.php 

In my PhpUnit.xml, I have:

<?xml version="1.0" encoding="UTF-8"?>
<phpunit verbose="false">
  <testsuites>
      <testsuite name="Application">
          <directory>./tests/Application/Tests</directory>
      </testsuite>
  </testsuites>
  <logging>
       <log type="coverage-text" target="php://stdout" showUncoveredFiles="false"/>
       <log type="json" target="/tmp/phpunit-logfile.json"/>
  </logging>
  <filter>
        <whitelist>
            <directory suffix=".php">./lib</directory>
        </whitelist>
  </filter>
</phpunit>

And in one of my test files, I open with:

namespace Application\Tests;

use Application\Dir1\File1;

class MyTest extends File1 {}

But it keeps on saying:

Class 'Application\Dir1\File1' not found

Where am I going wrong?

6
  • 1
    How do you load Dir1/File1.php from your test file? use statement doesn't mean that you should not require necessary files. Commented Mar 30, 2013 at 14:01
  • I tried using a bootstrap file which references an Autoload.php - but I wasn't sure what functionality to use to include all necessary files. I also thought PHPUnit.xml would automatically include the required files in the <filter> node. Is that not the case? Commented Mar 30, 2013 at 14:03
  • Just try to put require_once statement in the beginning and it should work. Commented Mar 30, 2013 at 14:04
  • 5
    So for every test I write, I have to require_once every file? Doesn't that defeat the whole purpose of using namespaces to autoload files? Seems a bit hacky... Commented Mar 30, 2013 at 14:06
  • You acan use this approach: php.net/manual/en/language.oop5.autoload.php Commented Mar 30, 2013 at 14:07

4 Answers 4

28

If you installed PHPUnit using Composer then you can use Composers autoloader. The easiest way to do so would be to add:

"autoload":{
    "psr-0":{
        "your-app-directory":""
    }
}

to composer.json

Sign up to request clarification or add additional context in comments.

3 Comments

I installed phpunit with composer and this does not solve the problem. Even using psr-4 and even swapping "your-app-directory" and ""
@Leggy7 can you send me what your trying to use
please mention to use 'composer dump-autoload'
5

Even if you use use, you still have to include the file, either by using include, require, include_once, or require_once, or by using spl_autoload_register to include the file, like so:

spl_autoload_register(function ($class)
{
    include '\lib\\' . $class . 'php';
});

When you then try to use Application\Dir1\File1 the script will automatically run include '\lib\Application\Dir1\File1.php'

4 Comments

You're right. But I want to get away from manually specifying the dependencies and move towards a more automated solution. My solution uses a way of doing that - but thanks anyway :)
How is your way more automated? It looks pretty much the same, just with more overhead.
Well, for one, this isn't handling directory separators (for different OS's), whereas the more comprehensive class does. But you did point me in the right direction - so it's only fair I mark this as the accepted solution.
Good point on the DS. Although you can simply that with str_replace('\\', DIRECTORY_SEPARATOR, $class);.
3

I had the same issue. I'm using composer as well and the only thing that solved it for me was the following:

  1. add to your composer.json file in the autoload section a class map section with your root namespace

    "autoload":  {
            "classmap": ["namespaceRoot/"]
    }
    
  2. execute composer dump-autoload command in order to recreate your autoload files (with all the class mappings!)

1 Comment

the composer dump-autoload solved my 1 hour headache :D, thanks mate
2

I found this really useful class autoloader by Jonathan Wage which allows PHPUnit tests to access namespaces from different directories. In my bootstrap.php, I just specified the location and associated module namespace:

require_once 'SplClassLoader.php';

$classLoader = new SplClassLoader('Application', dirname(__FILE__) . '/../lib');
$classLoader->register();

2 Comments

+1 for mentioning bootstrap.php. That's where my setup loads out custom autoader.
I did exactly this, but it cannot find the classes then. It also seems to not recursively go into all directories.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.