Symfony 2.6 overrides PHPUnit_Framework_Error - php

I have a unit tested application which we have updated from symfony 2.3 to 2.6. We followed all upgrading docs and had to change only some minor stuff.
Everything is working perfectly, except for the PHPUnit tests.
We have 2 seperate runs, one for only testing the entity classes, which is fired on a pre-commit hook. and a second one which runs the full suite, with database setups and the whole nine yards.
Now since the upgrade to 2.6, the PHPUnit_Framework_Error thrown in the unit tests have been replaced by Symfony's Symfony\Component\Debug\Exception\ContextErrorException, this failing all tests like this:
/**
* #dataProvider objectTestDataProvider
* #expectedException \PHPUnit_Framework_Error
*/
public function testCanNotSetClientToArbitraryValue($value)
Now I do not want to change this into the new Exception since running the entity-only test suite does not depend on symfony components, thus symfony is not loaded, thus the errors are the regular PHPUnit_Framework_Error so changing it makes these tests fail.
In other words, when I run one test class it works, once a symfony dependent test is run, it fails:
# runs perfectly
phpunit -c app/phpunit.xml --debug src/My/Bundle/Tests/Entity
# fails when reaching the tests that ran perfectly in previous command
phpunit -c app/phpunit.xml --debug
This new ErrorHandler seems undocumented, I couldnt find much about it in google except for the pull request and this small article
I've tried:
setting the SYMFONY_DEBUG=0 environment variable, but this doesnt seem to make any difference.
adding the debug.error_handler.throw_at: 0 parameter to my test_config.yml
edit:
On request by #cerad I've tried to isolate the tests to try and reproduce the code with as little as possible, Ive managed to reproduce with 4 tests:
class MyControllerTest extends WebTestCase
{
public function testRoutesLoaded_1()
{
$client = self::createClient();
/** #var Router $router */
$router = $client->getKernel()->getContainer()->get('router');
$this->assertEquals('/menu', $router->generate('front_menu'));
}
/**
* #expectedException \PHPUnit_Framework_Error
*/
public function testCreateOrder_1()
{
new Order(); // required parameter missing
}
public function testRoutesLoaded_2()
{
$client = $this->createNewFrontClient();
/** #var Router $router */
$router = $client->getKernel()->getContainer()->get('router');
$this->assertEquals('/menu', $router->generate('front_menu'));
}
/**
* #expectedException \PHPUnit_Framework_Error
*/
public function testCreateOrder_2()
{
new Order(); // required parameter missing
}
}
As you can see, I just run the same exact test 2 times, but still the last one results in an error:
MyControllerTest::testCreateOrder_2
Failed asserting that exception of type "Symfony\Component\Debug\Exception\ContextErrorException" matches expected exception "\PHPUnit_Framework_Error"

Since I did not get any replies here, I posted an issue on Symfony's github and they confirmed this was incorrect behavior.
The issue was resolved and is merged in 2.6-dev.

Related

Can we skip entire cest class in codeception?

I need to skip all the tests in the following cest class and currently I am skipping individual tests with #skip annotation. Is there any way I can skip execution at the class level itself, instead of individually skipping each test?
Currently I am skipping individual tests like this:
Class MyTests{
/**
* #skip Skip message
*/
public funtion test1(){
// Test steps
}
/**
* #skip Skip message
*/
public function test2(){
// Test steps
}
}
I tested it with Codeception 5 and #skip message works above class too.
I discovered a number of related issues and raised https://github.com/Codeception/Codeception/issues/6615

PHPUnit + Symfony: Crawler Follow Redirects Causes SegFault

I have a simple PHPUnit/Symfony WebTestCase set up to test our site's login form.
$form = $crawler->filter("#register")->form();
// set form values
$crawler = $this->client->submit($form);
The form will submit to /register, and then redirect to /registered on success (and 200/OK back to /register on failure).
If I use either $this->client->followRedirects(); before block above, or $this->client->followRedirect(); after the submit, I get a segfault. There's really no indication of where the segfault is taking place.
Something else of note: if I run JUST the tests in this tests parent class (2 tests) i.e. using --filter [THE CLASS] it runs fine. If I try to run this test, along with the full suite (~15 tests), I get the segfault.
I've tried giving phpunit more memory using the -d flag, but that doesn't really help.
The problem can be in controller work in conjunction with other component.
I suggest you to use the Process Isolation in PHPUnit so you can run the critical test in a separate PHP process. As Example, you can use the following annotations for:
Indicates that all tests in a test class should be run in a separate PHP process:
/**
* #runTestsInSeparateProcesses
*/
class MyTest extends PHPUnit_Framework_TestCase
{
// ...
}
Indicates that a test should be run in a separate PHP process:
class MyTest extends PHPUnit_Framework_TestCase
{
/**
* #runInSeparateProcess
*/
public function testInSeparateProcess()
{
// ...
}
}
Hope this help

Laravel 4 workbench class not found

I'm trying to develop a package in laravel 4 - my first attempt at a package.
I found a couple of tutorials which I've tried to follow:
http://jasonlewis.me/article/laravel-4-develop-packages-using-the-workbench
and
http://culttt.com/2013/06/24/creating-a-laravel-4-package/
and of course in the official documentation.
I've followed the basic structure to create the framework. However on loading the app I get a class not found error. This relates directly to the serviceprovider I have placed in the app.php file.
here's my entry in the providers array:
'Longestdrive\Calendar\CalendarServiceProvider'
My folder structure is:
laravel/workbench/longestdrive/calendar/src/Longestdrive/Calendar
My service provider has the following entries:
<?php namespace Longestdrive\Calendar;
use Illuminate\Support\ServiceProvider;
class CalendarServiceProvider extends ServiceProvider {
/**
* Indicates if loading of the provider is deferred.
*
* #var bool
*/
protected $defer = false;
/**
* Bootstrap the application events.
*
* #return void
*/
public function boot()
{
$this->package('longestdrive/calendar');
}
/**
* Register the service provider.
*
* #return void
*/
public function register()
{
//
}
/**
* Get the services provided by the provider.
*
* #return array
*/
public function provides()
{
return array();
}
}
I've double checked to spelling and ran a composer dump-autoload both from the root of the project and the root of the package.
I've run out of ideas for solving the class not found any ideas where I've gone wrong?
The line producing the error is this one:
C:\wamp\www\googleapi\laravel\vendor\laravel\framework\src\Illuminate\Foundation\ProviderRepository.php
Any help appreciated
Thanks
Update:
I ran a composer update as suggested in the workbench/package folder with a response nothing to update. I then ran composer at the root of the project and an error was produced:
[RuntimeException]
Error Output: PHP Fatal error: Class 'Longestdrive\Calendar\CalendarServiceProvider' not found
in C:\wamp\www\googleapi\laravel\vendor\laravel\framework\src\Illuminate\Foundation\ProviderRe
pository.php on line 123
I probably posted the wrong error line earlier. The full exception response is:
Class 'Longestdrive\Calendar\CalendarServiceProvider' not found
THe error extract:
* #param \Illuminate\Foundation\Application $app
* #param string $provider
* #return \Illuminate\Support\ServiceProvider
*/
public function createProvider(Application $app, $provider)
{
return new $provider($app);
}
which I assume relates to the service provider loader not finding the CalendarServiceProvider?
I found that running composer install from within the workbench/[vendor]/[package] folder solved the problem.
I encountered the same error, so I went deeper on its flow to knew what happens.
So dissecting a little bit basically, in the bootstrap phase, when bootstrap/autoload.php is loaded it runs at the end:
if (is_dir($workbench = __DIR__.'/../workbench'))
{
Illuminate\Workbench\Starter::start($workbench);
}
This requires EVERY workbench/vendor/package/**/**/**/autoload.php he found (by using Symfony Finder Component)
$finder->in($path)->files()->name('autoload.php')->depth('<= 3');
That's important because it's expecting to find workbench/vendor/package/vendor/autoload.php.
Successively in bootstrap/start.php it gets the 'providers' defined in config/app.php and try to load each of them:
$providers = $config['providers'];
$app->getProviderRepository()->load($app, $providers);
and then in ProviderRepository.php
foreach ($providers as $provider)
{
$instance = $this->createProvider($app, $provider);
so we'll end up with:
public function createProvider(Application $app, $provider)
{
return new $provider($app);
where it tried to create an instance of a class isn't really autoloaded. And so that's why the exception thrown!
In conclusion...
As #Ray said, by removing his Service from 'providers' => array( no error is thrown cause return new $myServiceDeclaredInProviderArray($app); never fires for that service.
As #Andrew Holt said
I found that running composer install from within the workbench/[vendor]/[package] folder solved the problem.
He's absolutely right because this create the autoload vendor dir and files, and everything works as we expect it to because it finds the autoload files:
$finder->in($path)->files()->name('autoload.php')->depth('<= 3');
Me
php artisan dump-autoload works as well if you remove the service from the providers array
In addition to #ilpaijin's and #Andrew Holt's answer, there sometimes comes the need (when there's a new version of Laravel) to run composer update within the workbench/vendor/package folder.
Also, as noted here, the composer.json within the package must require the same version of illuminate/support as the one required of laravel/framework in the project root's composer.json.
Thanks to #biscii note that one should use:
"illuminate/support": "4.1.x"
instead of
"illuminate/support": "4.x"

Doctrine Annotation failing

Currently I'm trying to implement the Doctrine CouchDB Bundle in a Silex Application. At one point the complete site ends in a 500/internal server error in my local dev stack. Setting breakpoints and debugging them with XDebug and PHPStorm hasn't brought me to any result so far. Apache Error logs are empty, PHP error logs as well and error_reporting(-1); still doesn't give any output. Probably the problem is the reflection class usage in there.
Everything works well, until I try to use CouchDB Annotations from
use Doctrine\ODM\CouchDB\Mapping\Annotations as CouchDB;
and use them in my Document
/** #CouchDB\Document */
class Station
{
/**
* #Index
* #Id
*/
private $id;
If I remove the CouchDB\ above, everything works. But if I remove it, and use #Id(strategy="ASSIGNED"), I run into the exact same problem.
I tried to register the Annotations in several ways without luck. #Ocramius suggested in chat that I should simply override the Autoloader, which worked well with getting beyond some other problems, but not for that case (just adding it here in case someone else needs it).
AnnotationRegistry::registerLoader( function( $className ) {
return class_exists( $className );
} );
Try to use
/**
* #CouchDB\Index
* #CouchDB\Id
*/
instead of
/**
* #Index
* #Id
*/
You can also solve this by adding this line before you run your Silex Application (probably in index.php).
AnnotationRegistry::registerLoader('class_exists');

PHPUnit is no longer running after ArrayCollection (Doctrine 2) initialization in Netbeans

I'm working on a PHP project and use PHPUnit and Doctrine 2. I use the latest version at all. I wrote a lot of tests to test all the classes, functions and behavior. The tests are always running. Everything worked fine. Since I use Doctrine, I have applied the best-practice tips and initializes the ArrayCollection in the constructor.
public function __construct($username, $eMail, $password1, $password2) {
$this->quiz = new ArrayCollection();
$this->sessions = new ArrayCollection();
$this->setUsername($username);
$this->setEMail($eMail);
$this->setPassword('', $password1, $password2);
}
The include of the ArrayCollection is:
use Doctrine\Common\Collections\ArrayCollection;
After this point, the PHPUnit tests are no longer running.
When I comment the line with the initialization all test run again. The members quiz and sessions are private. The application generally works.
I'm new with Doctrine 2 and PHPUnit. I've tried many things until now like different includes in the testcase etc. But nothing has helped.
Maybe I forgot something in the testcase. Between the step initialization of the ArrayCollection and without initialization I have changed nothing in the testcase.
The testcase looks like this:
namespace Model;
require_once dirname(__FILE__) . '/../../Model/User.php';
/**
* Test class for User.
* Generated by PHPUnit on 2012-04-03 at 14:48:39.
*/
class UserTest extends \PHPUnit_Framework_TestCase {
/**
* #var User
*/
protected $user;
// constructor of the test suite
function UserTest($name) {
$this->PHPUnit_TestCase($name);
}
/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*/
protected function setUp() {
$username = 'musteruser';
$eMail = 'must#muster.ch';
$pw = 'muster.muster';
$this->user = new User($username, $eMail, $pw, $pw);
}
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*/
protected function tearDown() {
unset($this->user);
}
Right now I really have no idea what could be the problem. Maybe someone has already experienced the same thing or has any idea what could be the problem.
Thanks for any help.
You may need to ensure that the Doctrine\Common folder is on the include path for your test cases when you call PHPUnit.
Are you customizing any class loaders for your application, since you need to do the same for your tests.
I have found a solution for the problem. I created a file with the name bootstrap.php with the following content:
// Import the ClassLoader
use Doctrine\Common\ClassLoader;
// Autoloader for Doctrine
require '/../../php/PEAR/Doctrine/Common/ClassLoader.php';
// Autoloading for Doctrine
$doctrineClassLoader = new ClassLoader('Doctrine', realpath(__DIR__ . '/../../php/PEAR'));
$doctrineClassLoader->register();
The file is placed in the home directory of Test Files, the part for Unit Testing in a NetBeans project. The important thing is, that is nothing to edit in the testcases.

Categories