PHPUnit 3.7.19和Symfony2损坏的测试 [英] PHPUnit 3.7.19 and Symfony2 broken tests

查看:57
本文介绍了PHPUnit 3.7.19和Symfony2损坏的测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm developing some test for a Symfony2.0 project and running them with PHPUnit.

在我的PC上工作正常,但在其他环境中尝试使用它们时,测试将失败.我以为问题是php版本,但在不同的环境中运行它们后我迷路了.

On my PC works fine but trying them in other environments the tests fails. I thought the problem was php version but after run them in differents environments I'm lost.

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

具有Ubuntu 12.10和PHP 5.4.6的2台PC:

2 PC with Ubuntu 12.10 and PHP 5.4.6:

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

此错误发生在扩展 Symfony \ Bundle \ FrameworkBundle \ Test \ WebTestCase 的类上,在该类上覆盖了setUp()和tearDown()方法.

This error is on a class which extends Symfony\Bundle\FrameworkBundle\Test\WebTestCase where is overwritten the setUp() and tearDown() methods.

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:

    • 2 PC, one with Ubuntu 12.10 and PHP 5.4.6 and other with Windows 7 and PHP 5.3.8:

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

    • 此错误是在扩展上述类的类而导致的,该类具有tearDown()方法错误,但是在这种情况下,该类可以工作,并且该错误是不同的,尽管与$ this-> container有关:

      This error is on a class which extends the above class that has tearDown() method wrong but in this case this class works and the error is different although is related with $this->container:

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

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

      The problem is I don't know why is this. If this is related to PHP, PHPUnit(All of us have the same version), Symfony2.0 or SO.

      好,问题解决了.

      第一:

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

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

      Had a wrong line of code in the class which has setUp() and tearDown() methods. A line like that:

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

      我对此行发表了评论,对不起:).但是我不知道为什么PHPUnit向我显示此错误而不是link方法错误.

      I had this line commented, sorry :). But I don't know why PHPUnit show me this error and not the error of link method.

      第二:

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

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

      In the others environments, the test database had not been deployed.

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

      This question will not help anyone but help me to try new things. Thanks!

      推荐答案

      这是PHPUnit的预期行为.

      It is an exected behavior for PHPUnit.

      我设法通过以下代码重现该错误:

      I managed to reproduce the error with the following code:

      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方法中触发的任何异常(以使打印机在执行结束时显示).

      To explain more clearly, PHPUnit will catch any exceptions triggered in the setUp method (in order for the printers to show at the end of the execution).

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

      After that you can see that the tearDown() is called to finish the test, but since the initialization of the attribute was never reached, a PHP error is issued, and PHPUnit will never reach the code where it shows all the exceptions that occurred.

      这就是为什么您没有得到例外的原因.要解决此问题,您需要确保将可能在设置中引发异常的所有代码包装在try() catch ()语句中,如下所示:

      That is why you did not get the exception. To fix this, you need to make sure that any code that can throw exceptions in the setup is wrapped in a try() catch () statement like this:

          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();
          }
      

      希望它对以后的人有所帮助.

      Hope it helps someone in the future.

      这篇关于PHPUnit 3.7.19和Symfony2损坏的测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆