PHPUnit 3.7.19和Symfony2破坏了测试

时间:2013-05-10 09:05:12

标签: unit-testing symfony phpunit

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

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

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

  • 2台带有Ubuntu 12.10和PHP 5.4.6的PC:

    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->容器有关:

//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

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

这个问题对任何人都没有帮助,只能帮助我尝试新事物。谢谢!

1 个答案:

答案 0 :(得分: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将catch setUp方法中触发的任何异常(以便打印机在执行结束时显示)。

之后你可以see调用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();
    }

希望将来帮助某人。