PHPUnit:找不到致命错误类ClassName

时间:2013-06-01 11:17:49

标签: php phpunit codeigniter-2

我正在尝试为CodeIgniter应用程序构建单元测试环境。我正在关注this book并让PHPUnit工作。

我正在测试模型中的一些代码:

    public function testPresent()
{
    $tracker = new Tracker_model();

    $tableObj = (object)array( 'type' => $this->expectedConstants['TABLE']);
    $visitsObj = (object)array( 'type' => $this->expectedConstants['VISITS']);

    $tableObj = $tracker->present($tableObj);
    $visitsObj = $tracker->present($visitsObj);

    $this->assertThat($tableObj, $this->isInstanceOf('Tracker_TablePresenter'));
    $this->assertThat($visitsObj, $this->isInstanceOf('Tracker_VisitsPresenter'));
}

正在测试的代码是:

    public function present($obj)
{
    if( isset($obj->type) )
    {
        switch($obj->type)
        {
            case self::VISITS: $type = 'Visits'; break;
            case self::TABLE: 
            default: $type = 'Table'; break;
        }

        $className = 'Tracker_'.$type.'Presenter';
        $obj = new $className($obj, 'tracker');
    }
    return $obj;
}

它应该加载文件Tracker_TablePresenter中的类presenters/tracker/TablePresenter.php。我无法解释这种机制背后的所有逻辑,因为它太长而且复杂,但我知道它有效,因为在另一台具有完全相同代码的计算机上它正在通过测试。相反,在我的计算机上,我收到此错误:

.......PHP Fatal error:  Class 'Tracker_TablePresenter' not found in /home/.../application/models/tracker_model.php on line 42

有关错误的更多信息:

PHP Stack trace:
PHP   1. {main}() /.../vendor/phpunit/phpunit/composer/bin/phpunit:0
PHP   2. PHPUnit_TextUI_Command::main() /.../vendor/phpunit/phpunit/composer/bin/phpunit:63
PHP   3. PHPUnit_TextUI_Command->run() /.../vendor/phpunit/phpunit/PHPUnit/TextUI/Command.php:129
PHP   4. PHPUnit_TextUI_TestRunner->doRun() /.../vendor/phpunit/phpunit/PHPUnit/TextUI/Command.php:176
PHP   5. PHPUnit_Framework_TestSuite->run() /.../vendor/phpunit/phpunit/PHPUnit/TextUI/TestRunner.php:349
PHP   6. PHPUnit_Framework_TestSuite->run() /.../vendor/phpunit/phpunit/PHPUnit/Framework/TestSuite.php:705
PHP   7. PHPUnit_Framework_TestSuite->runTest() /.../vendor/phpunit/phpunit/PHPUnit/Framework/TestSuite.php:745
PHP   8. PHPUnit_Framework_TestCase->run() /.../vendor/phpunit/phpunit/PHPUnit/Framework/TestSuite.php:775
PHP   9. PHPUnit_Framework_TestResult->run() /.../vendor/phpunit/phpunit/PHPUnit/Framework/TestCase.php:776
PHP  10. PHPUnit_Framework_TestCase->runBare() /.../vendor/phpunit/phpunit/PHPUnit/Framework/TestResult.php:648
PHP  11. PHPUnit_Framework_TestCase->runTest() /.../vendor/phpunit/phpunit/PHPUnit/Framework/TestCase.php:831
PHP  12. ReflectionMethod->invokeArgs() /.../vendor/phpunit/phpunit/PHPUnit/Framework/TestCase.php:976
PHP  13. Tracker_modelTest->testPresent() /.../vendor/phpunit/phpunit/PHPUnit/Framework/TestCase.php:976
PHP  14. Tracker_model->present() /.../application/tests/models/Tracker_modelTest.php:38

我正在研究Ubuntu,而另一个有代码工作的人正在使用Mac。这是我的php -v

的输出
PHP 5.4.9-4ubuntu2 (cli) (built: Mar 11 2013 16:09:26) 
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies
with Xdebug v2.3.0dev, Copyright (c) 2002-2013, by Derick Rethans

我也尝试将php降级到5.3,因为他使用的是5.3,但没有。同样的错误。 你能帮我理解发生了什么吗?

编辑:

这是文件TablePresenter.php

的内容
<?php

class Tracker_TablePresenter extends Presenter
{
public function values()
{
    $this->ci =& get_instance();
    if (!isset($this->values)) {
        $this->ci->load->model('value_model', 'value');
        $this->values = $this->ci->value->getManyForTracker($this->tracker->id);
    }
    return $this->values;
}
}

?>

编辑2:

我按照JoDev的建议修改了present函数中的代码,如下所示:

    public function present($obj)
{
if( isset($obj->type) )
{
    switch($obj->type)
    {
        case self::VISITS: $type = 'Visits'; break;
        case self::TABLE: 
        default: $type = 'Table'; break;
    }

    //use include, but require is to force an internal error if the file isn't founded!
    require_once('presenters/tracker/'.$type.'Presenter.php');

    $className = 'Tracker_'.$type.'Presenter';
    $obj = new $className($obj, 'tracker');
}
return $obj;
}

现在我收到了这个错误:

PHPUnit 3.7.21 by Sebastian Bergmann.

Configuration read from .../phpunit.xml

.......PHP Fatal error:  Class 'Tracker_TablePresenter' not found in .../application/models/tracker_model.php on line 61
PHP Stack trace:
PHP   1. {main}() .../vendor/phpunit/phpunit/composer/bin/phpunit:0
PHP   2. PHPUnit_TextUI_Command::main() .../vendor/phpunit/phpunit/composer/bin/phpunit:63
PHP   3. PHPUnit_TextUI_Command->run() .../vendor/phpunit/phpunit/PHPUnit/TextUI/Command.php:129
PHP   4. PHPUnit_TextUI_TestRunner->doRun() .../vendor/phpunit/phpunit/PHPUnit/TextUI/Command.php:176
PHP   5. PHPUnit_Framework_TestSuite->run() .../vendor/phpunit/phpunit/PHPUnit/TextUI/TestRunner.php:349
PHP   6. PHPUnit_Framework_TestSuite->run() .../vendor/phpunit/phpunit/PHPUnit/Framework/TestSuite.php:705
PHP   7. PHPUnit_Framework_TestSuite->runTest() .../vendor/phpunit/phpunit/PHPUnit/Framework/TestSuite.php:745
PHP   8. PHPUnit_Framework_TestCase->run() .../vendor/phpunit/phpunit/PHPUnit/Framework/TestSuite.php:775
PHP   9. PHPUnit_Framework_TestResult->run() .../vendor/phpunit/phpunit/PHPUnit/Framework/TestCase.php:776
PHP  10. PHPUnit_Framework_TestCase->runBare() .../vendor/phpunit/phpunit/PHPUnit/Framework/TestResult.php:648
PHP  11. PHPUnit_Framework_TestCase->runTest() .../vendor/phpunit/phpunit/PHPUnit/Framework/TestCase.php:831
PHP  12. ReflectionMethod->invokeArgs() .../vendor/phpunit/phpunit/PHPUnit/Framework/TestCase.php:976
PHP  13. Tracker_modelTest->testPresent() .../vendor/phpunit/phpunit/PHPUnit/Framework/TestCase.php:976
PHP  14. Tracker_model->present() .../application/tests/models/Tracker_modelTest.php:37

<h4>A PHP Error was encountered</h4>

<p>Severity: Warning</p>
<p>Message:  include(presenters/tracker/TablePresenter.php): failed to open stream: No such file or directory</p>
<p>Filename: models/tracker_model.php</p>
<p>Line Number: 58</p>

</div><div style="border:1px solid #990000;padding-left:20px;margin:0 0 10px 0;">

<h4>A PHP Error was encountered</h4>

<p>Severity: Warning</p>
<p>Message:  include(): Failed opening 'presenters/tracker/TablePresenter.php' for inclusion (include_path='.../vendor/phpunit/php-text-template:.../vendor/phpunit/phpunit-mock-objects:.../vendor/phpunit/php-timer:.../vendor/phpunit/php-token-stream:.../vendor/phpunit/php-file-iterator:.../vendor/phpunit/php-code-coverage:.../vendor/phpunit/phpunit:.../vendor/symfony/yaml:.../vendor/pdepend/pdepend/src/main/php:.../vendor/phpmd/phpmd/src/main/php:.:/usr/share/php:/usr/share/pear')</p>
<p>Filename: models/tracker_model.php</p>
<p>Line Number: 58</p>

</div>%                       

4 个答案:

答案 0 :(得分:2)

请您尝试使用以下方法包含该类:

public function present($obj)
{
    if( isset($obj->type) )
    {
        switch($obj->type)
        {
            case self::VISITS: $type = 'Visits'; break;
            case self::TABLE: 
            default: $type = 'Table'; break;
        }

        //use include, but require is to force an internal error if the file isn't founded!
        require_once('Presenters/Tracker/'.$type.'Presenter.php');

        $className = 'Tracker_'.$type.'Presenter';
        $obj = new $className($obj, 'tracker');
    }
    return $obj;
}

感谢此测试,您将能够知道错误是在autoloader还是其他任何地方! 并告诉我追加什么...

[EDIT @ 13/06 / 2013 10:00]

树中调用TablePresenter的文件在哪里?

要解决问题,你(在我看来)有三种可能性:
-1)在服务器的include_path中添加Presenter的父目录!     (要检索实际包含,请使用get_include_path()
-2)一定要使用好的URL来包含文件
-3)使用绝对URL

答案 1 :(得分:0)

我敢打赌它与你机器上的文件权限有关。该脚本无法找到该文件,因为Apache无法打开它。

答案 2 :(得分:0)

听起来像是一个案例敏感问题(@jospratik的问题)。据我所知,OSX不区分大小写。所以这是你在使用linux vs mac / win时会遇到的问题。

将文件夹名称更改为以

等大写字母开头
Presenters/Tracker/VisitsPresenter.php

答案 3 :(得分:0)

在我看来,类似于'Tracker_TablePresenter'这个问题无法找到。你使用了正确的命名空间吗?