Domanda

I have a small unit test for a very simple class. Here is the class I want to test:

<?php
namespace MyApp\sys;

class Auth
{
    // ...

    public static function getInstance()
    {
    if(!isset(self::$_instance))
        self::$_instance = new Auth();

    return self::$_instance;
    }

    public function authenticate($sMethod, $sData, $sAuth)
    {
        // ...
        return $this->authSession();
    }

    public function authSession()
    {
        // ...
        $oHandler = new SessionHandler();
    }
}

Here is the SessionHandler class:

<?php

namespace MyApp\sys;

class SessionHandler implements \SessionHandlerInterface
{
    public function open($sSavePath, $sSessionId)
    {
        // ...
    }

    public function close()
    {
        // ...
    }

    public function read($sSessionId)
    {
        // ...
    }

    public function write($sSessionId, $sSessionData)
    {
        // ...
    }

    public function destroy($sSessionId)
    {
        // ...
    }

    public function gc($iMaxLifetime)
    {
        // ...
    }
}

Here is the simple unit test:

<?php
namespace Test\MyApp\sys;

use PHPUnit_Framework_TestCase;

class AuthTest extends PHPUnit_Framework_TestCase
{
    protected function setUp()
    {
        parent::setUp();
    }

    protected function tearDown()
    {
        parent::tearDown();
    }

    public function testGetInstance()
    {
        $oAuth = \MyApp\sys\Auth::getInstance();
        $this->assertInstanceOf('\MyApp\sys\Auth', $oAuth);

        return $oAuth;
    }

    /**
     * @depends testGetInstance
     */
    public function testAuthenticate(\MyApp\sys\Auth $oAuth)
    {
        $res = $oAuth->authenticate(null, null, null);
    }
}

I have the following phpunit.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<phpunit
    bootstrap="bootstrap.php"
    convertErrorsToExceptions="true"
    convertNoticesToExceptions="true"
    convertWarningsToExceptions="true"
    stopOnError="true"
    stopOnFailure="true"
    strict="false"
    verbose="true">
    <testsuites>
        <testsuite name="Authentication">
            <directory suffix="Test.php">
                ./MyApp/sys/
            </directory>
        </testsuite>
    </testsuites>
</phpunit>

... and the following bootstrap.php file:

<?php
define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../'));
define('APPLICATION_TEST_PATH', realpath(dirname(__FILE__)));

spl_autoload_register(function($sClas) {
    $nClass = str_replace("\\", "/", $sClas);
    require_once APPLICATION_PATH . '/' . $nClass . ".php";
});

The directory structure is something like this:

- MyProject/
   - MyApp/
      - sys/
         . Auth.php
         . SessionHandler.php
   - Test/
      - MyApp/
         - sys/
            . AuthTest.php
      . bootstrap.php
      . phpunit.xml

This is how I try running this small unit test from command line (and the result I get):

# phpunit MyApp/sys/AuthTest.php 
PHPUnit 3.7.19 by Sebastian Bergmann.

Configuration read from /Users/pmpro/Code/Snevens/MyProject/Tests/phpunit.xml

.PHP Fatal error:  {closure}(): Failed opening required '/Users/pmpro/Code/Snevens/MyProject/SessionHandlerInterface.php' (include_path='.:/usr/share/pear') in /Users/pmpro/Code/Snevens/MyProject/Tests/bootstrap.php on line 7

Fatal error: {closure}(): Failed opening required '/Users/pmpro/Code/Snevens/MyProject/SessionHandlerInterface.php' (include_path='.:/usr/share/pear') in /Users/pmpro/Code/Snevens/MyProject/Tests/bootstrap.php on line 7

I thought it would be a problem with the registered autoload function, so I decided to skip the class autoloading in case it's SessionHandlerInterface just to see what would happen:

spl_autoload_register(function($sClas) {
    if("SessionHandlerInterface" == $sClas)
        return;

    $nClass = str_replace("\\", "/", $sClas);
    require_once APPLICATION_PATH . '/' . $nClass . ".php";
});

and this was the result:

# phpunit MyApp/sys/AuthTest.php 
PHPUnit 3.7.19 by Sebastian Bergmann.

Configuration read from /Users/pmpro/Code/Snevens/MyProject/Tests/phpunit.xml

.PHP Fatal error:  Interface 'SessionHandlerInterface' not found in /Users/pmpro/Code/Snevens/MyProject/MyApp/sys/SessionHandler.php on line 9

Fatal error: Interface 'SessionHandlerInterface' not found in /Users/pmpro/Code/Snevens/MyProject/MyApp/sys/SessionHandler.php on line 9

If I invoke SessionHandler.php directly from the command line, it returns no error:

# php SessionHandler.php
(returns nothing)

What am I doing wrong or what am I missing?

This only happens with SessionHandlerInterface. I tried running only testGetInstance, making the Auth class implement ArrayAccess, for example, and it does not complain at all. If I make Auth class implement SessionHandlerInterface it immediately complains.

I'm running PHP 5.4.13 and PHP Unit 3.7.19

È stato utile?

Soluzione

Ok, so it was a silly problem related to the PHP version being referenced in phpunit script. At the top of /usr/bin/phpunit, the path was refering to PHP 5.3.* which apparently does not support SessionHandlerInterface. So I just had to change that path to the correct PHP version and is now working.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top