问题
I'm developing some test for a Symfony2.0 project and running them with PHPUnit.
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.
My environment is Ubuntu 12.04 and PHP 5.3.10 => Works fine.
2 PC with Ubuntu 12.10 and PHP 5.4.6:
Fatal error: Call to a member function get() on a non-object
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, 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
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();
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.
Edit:
Ok, problems solved.
First:
Fatal error: Call to a member function get() on a non-object
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();
I had this line commented, sorry :). But I don't know why PHPUnit show me this error and not the error of link method.
Second:
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!
回答1:
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
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).
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.
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.
来源:https://stackoverflow.com/questions/16478669/phpunit-3-7-19-and-symfony2-broken-tests