非常に単純なクラスの小さな単体テストがあります。テストしたいクラスは次のとおりです。
<?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();
}
}
以下は SessionHandler クラスです。
<?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)
{
// ...
}
}
簡単な単体テストは次のとおりです。
<?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);
}
}
次の phpunit.xml ファイルがあります。
<?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>
...そして次のbootstrap.phpファイル:
<?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";
});
ディレクトリ構造は次のようなものです。
- MyProject/
- MyApp/
- sys/
. Auth.php
. SessionHandler.php
- Test/
- MyApp/
- sys/
. AuthTest.php
. bootstrap.php
. phpunit.xml
これは、コマンドラインからこの小さな単体テストを実行しようとする方法です(および得られた結果):
# 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
登録されたオートロード機能に問題があると思ったので、何が起こるかを確認するために、SessionHandlerInterface の場合に備えて、クラスのオートロードをスキップすることにしました。
spl_autoload_register(function($sClas) {
if("SessionHandlerInterface" == $sClas)
return;
$nClass = str_replace("\\", "/", $sClas);
require_once APPLICATION_PATH . '/' . $nClass . ".php";
});
これが結果でした:
# 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
コマンドラインから SessionHandler.php を直接呼び出すと、エラーは返されません。
# php SessionHandler.php
(returns nothing)
私は何を間違っていますか、または何が欠けていますか?
これはSessionHandlerInterfaceでのみ発生します。たとえば、 AuthクラスにArrayAccessを実装させて、testGetInstanceのみを実行してみましたが、まったく文句はありません。AuthクラスにSessionHandlerInterfaceを実装させると、すぐに文句を言います。
PHP 5.4.13 と PHP Unit 3.7.19 を実行しています