1

我正在为 Symfony2.0 项目开发一些测试并使用 PHPUnit 运行它们。

在我的电脑上工作正常,但在其他环境中尝试测试失败。我以为问题出在 php 版本上,但是在不同的环境中运行它们后,我迷路了。

  • 我的环境是 Ubuntu 12.04 和 PHP 5.3.10 =>工作正常。

  • 2 台装有 Ubuntu 12.10 和 PHP 5.4.6 的电脑:

    Fatal error:  Call to a member function get() on a non-object
    

此错误出现在扩展Symfony\Bundle\FrameworkBundle\Test\WebTestCase的类上,其中覆盖了 setUp() 和 tearDown() 方法。

public function setUp()
{
    $this->client = static::createClient();
    $this->client->followRedirects(true);

    $crawler = $this->client->request('GET', '/admin/login');

    $loginForm = $crawler->selectButton('save')->form(array(
        '_username' => 'user',
        '_password' => 'pass'
        ));
    $this->client->submit($loginForm);

    $this->container = $this->client->getContainer();
    parent::setUp();
}

public function tearDown()
{
    //Here is get() on a non-object, $this->container doesn't exists
    $this->container->get('doctrine.odm.mongodb.document_manager')->getConnection()->close();
    parent::tearDown();
}
  • 2 台 PC,一台装有 Ubuntu 12.10 和 PHP 5.4.6,另一台装有 Windows 7 和 PHP 5.3.8:

    PHP Fatal error:  Call to a member function getSite() on a non-object
    

此错误发生在扩展上述类的类上,该类的 tearDown() 方法错误,但在这种情况下,此类有效,错误不同,尽管与 $this->container 相关:

//In this case, the user doesn't exists
$site = $this->container->get('security.context')
        ->getToken()->getUser()->getSite();

问题是我不知道这是为什么。如果这与 PHP、PHPUnit(我们都有相同的版本)、Symfony2.0 或 SO 有关。

编辑:

好的,问题解决了。

第一的:

Fatal error:  Call to a member function get() on a non-object

在具有 setUp() 和 tearDown() 方法的类中有错误的代码行。像这样的一行:

$link = $crawler->filter('a:contains("Test")')->eq(1)->link();

我评论了这一行,对不起:)。但我不知道为什么 PHPUnit 显示这个错误而不是链接方法的错误。

第二:

PHP Fatal error:  Call to a member function getSite() on a non-object

在其他环境中,尚未部署测试数据库。

这个问题不会帮助任何人,但会帮助我尝试新事物。谢谢!

4

1 回答 1

0

这是 PHPUnit 的一种执行行为。

我设法使用以下代码重现错误:

final class ExceptionErrorTest extends PHPUnit_Framework_TestCase
{
    /**
     * @var MyObject
     */
    private $object;

    public function setUp() {
        throw new \RuntimeException();
        $this->object = new MyObject();
    }

    public function testItShouldNeverBeCalled()
    {
        var_dump('never called');
    }

    public function tearDown()
    {
        $this->object->neverCalled();
    }
}

class MyObject
{
    public function neverCalled() {
        return true;
    }
}

// will ouput PHP Fatal error: 
Call to a member function neverCalled() on a non-object in ExceptionErrorTest.php on line 22

为了更清楚地解释,PHPUnit 将捕获方法中触发的任何异常setUp(以便打印机在执行结束时显示)。

之后您可以看到调用tearDown()了 以完成测试,但由于从未达到属性的初始化,因此发出 PHP 错误,并且 PHPUnit 永远不会到达显示所有发生异常的代码。

这就是为什么你没有得到例外。要解决此问题,您需要确保任何可以在设置中引发异常的代码都包含在try() catch ()如下语句中:

    public function setUp() {
        try {
            throw new \RuntimeException('My message');
        } catch (\Exception $e) {
            echo 'An error occured in the setup: ' $e->getMessage();
            die;
        }

        $this->object = new MyObject();
    }

希望它对将来的人有所帮助。

于 2015-10-22T14:01:00.410 回答