PHPUnit测试可能会出现致命错误吗?

时间:2011-09-02 20:48:41

标签: php unit-testing phpunit fatal-error

我正在为类加载器编写一些单元测试,第一个测试是断言尝试引用类而不先加载它确实会失败。

测试如下:

/**
 * @expectedException PHPUnit_Framework_Error
 */
public function testInstantiateUnloadedClass() {
    $foo = new Foo();
}

可悲的是,运行测试会产生以下消息:

  

PHP致命错误:第7行的/Users/jfvaren/workspace/classloader/ClassLoaderTest.php中找不到类'Foo'

我必须接受这是不可行的吗?

3 个答案:

答案 0 :(得分:4)

调用class_exists(),这会尝试自动加载类,如果不能,则返回布尔值假。

http://php.net/manual/en/function.class-exists.php

答案 1 :(得分:2)

要测试该类是否已被实例化,您可以简单地执行以下操作:

try {
     if( !class_exists( "Foo" ) )
          throw new Exception( "Foo does not exist." );
}catch( Exception $e ){
     $e->showMessage();
}

此外,如果要在实际引用时测试它是否存在(并且您不想先执行class_exists),则可以在AutoLoader中执行此操作。我在下面列出了更多内容,以及一个示例模具声明。

有关AutoLoader的说明

现在,可能是偏离主题的,如果你想能够动态地包含一个类而不明确地引用它,你可以通过实例化一个AutoLoader。引用类时,AutoLoaders会查找类文件,然后在尝试使用它之前将其包含在内。

因此,例如,您需要在Test.php文件中包含AutoLoader.php,以及使用该类的所有其他文件。然后,该文件将根据需要包含其他文件。

为此,您需要设置AutoLoader.php文件。它需要看起来像这样:

// This tells PHP what to use to load the functions
ini_set( 'unserialize_callback_func', '__autoload' );

// Create an array pairing class names to their file include path
$myClasses = array( "Foo" => "Foo.php", "Bar" => "Bar.php" );

class AutoLoader {

    static function autoload( $class ){
        if( !in_array( $class, $myClasses ) )
            die( "The class {$class} doesn't exist!" );
        require( $myClasses[$class] );
    }

}

if( function_exists( 'spl_autoload_register' ) ) {
    spl_autoload_register( array( 'AutoLoader', 'autoload' ) );
} else {
    function __autoload( $className ){
        # When called, load a previously unloaded class
        AutoLoader::autoload( $className );
    }
}

答案 2 :(得分:1)

似乎无法捕捉致命错误。因此,不要在__autoload中使用require,而是可以使用include with if语句并生成特定的异常。