Codeception / Codeception

Full-stack testing PHP framework
http://codeception.com
MIT License
4.76k stars 1.3k forks source link

Laravel5 module: Laravel 5.3.0-Dev throws TypeError exception for Codeception\Lib\Connector\Laravel5\ExceptionHandlerDecorator #3420

Closed bonsi closed 8 years ago

bonsi commented 8 years ago

What are you trying to achieve?

Using the Codeception Laravel5 module together with Laravel Framework version 5.3.0-Dev.

I've already found a solution by letting Codeception\Lib\Connector\Laravel5\ExceptionHandlerDecorator implement the Illuminate\Contracts\Debug\ExceptionHandler contract. Will provide a pullrequest later today.

What do you get instead?

SecureSessionCest: Setup a secure session
Signature: SecureSessionCest:setup_a_secure_session
Test: tests/api/SecureSessionCest.php:setup_a_secure_session
Scenario --

  [Symfony\Component\Debug\Exception\FatalThrowableError]                                                                                                                                     
  Type error: Argument 3 passed to Illuminate\Queue\Worker::__construct() must implement interface Illuminate\Contracts\Debug\ExceptionHandler, instance of Codeception\Lib\Connector\Laravel5\ExceptionHandlerDecorator given, called in /home/vagrant/dispatcher/vendor/laravel/framework/src/Illuminate/Queue/QueueServiceProvider.php on line 80

Provide test source code if related

// paste test

Details

The actual issues here lies in Codeception\Lib\Connector\Laravel5:

$decorator = new ExceptionHandlerDecorator($this->app['Illuminate\Contracts\Debug\ExceptionHandler']);
$decorator->exceptionHandlingDisabled($this->exceptionHandlingDisabled);
$this->app->instance('Illuminate\Contracts\Debug\ExceptionHandler', $decorator);

where the laravel exception handler is replaced in the laravel service container by an instance of Codeception\Lib\Connector\Laravel5\ExceptionHandlerDecorator, which does not implement the Illuminate\Contracts\Debug\ExceptionHandler contract. Because of a recent rework (see commit) Laravel Queue Workers, the Worker constructor now expects an exception handler which implements Illuminate\Contracts\Debug\ExceptionHandler.

class_name: ApiTester
modules:
    enabled:
        - Helper\Api
        - Asserts
        - REST:
            depends: Laravel5
        - Laravel5:
            environment_file: .env.testing
            run_database_migrations: true
janhenkgerritsen commented 8 years ago

What does your test and relevant application code look like? I'd like to replicate the problem myself before I merge your PR.

bonsi commented 8 years ago

I can not show you the original code since it's proprietary, but for the test code below, the same exception is thrown:

$I->wantTo('Setup a secure session');

$I->haveHttpHeader('Content-Type', 'text/xml'); $I->sendPOST('api/dispatcher_xml', 'data');

$I->seeResponseCodeIs(200); $I->seeResponseIsXml();

Result:

1) SecureSessionCest: Setup a secure session Test tests/api/SecureSessionCest.php:setup_a_secure_session

[TypeError] Argument 3 passed to Illuminate\Queue\Worker::__construct() must implement interface Illuminate\Contracts\Debug\ExceptionHandler, instance of Codeception\Lib\Connector\Laravel5\ExceptionHandlerDecorator given, called in /home/vagrant/dispatcher/vendor/laravel/framework/src/Illuminate/Queue/QueueServiceProvider.php on line 80


I was in doubt whether our definition of functional and acceptence tests were one and the same, and therefore I maybe had to use the snippet to setup Laravel as shown in the codeception docks:

require 'bootstrap/autoload.php'; $app = require 'bootstrap/app.php'; $app->loadEnvironmentFrom('.env.testing'); $app->instance('request', new \Illuminate\Http\Request); $app->make('Illuminate\Contracts\Http\Kernel')->bootstrap();

but that made no difference at all.

I also made sure the webserver was not used for the test above.

Regards, Ivo

On Wed, Aug 10, 2016 at 1:00 PM, Jan-Henk Gerritsen < notifications@github.com> wrote:

What does your test and relevant application code look like? I'd like to replicate the problem myself before I merge your PR.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Codeception/Codeception/issues/3420#issuecomment-238834232, or mute the thread https://github.com/notifications/unsubscribe-auth/ABFb-DIbdSdfeM-Rz-fo7hTBrDM4xH46ks5qea81gaJpZM4JgDbX .

janhenkgerritsen commented 8 years ago

And can you give me an idea of the application code that leads to a queue worker being constructed? Just some pseudo code is fine.

bonsi commented 8 years ago

I'm currently rebuilding/integrating a legacy PHP appl which reads XML commands (kinda like soap) and responds accordingly. I'm using Laravel for all the goodies like migrations, and so far I only created one route (POST /api/xml_dispatcher) in Laravel, and one controller which responds to this uri. In the controller method, the XML message in the POST params is extracted and passed on to the entry point class of the legacy code. As far as I can tell, the queue worker is instantiated by default in a laravel 5.3 bootstrap, but the big difference with 5.2 is that the queue worker now has the exception handler as a dependency. My code does not explicitly construct the laravel queue worker, it's done so by default by laravel itself.

On Thu, Aug 11, 2016 at 12:51 PM, Jan-Henk Gerritsen < notifications@github.com> wrote:

And can you give me an idea of the application code that leads to a queue worker being constructed? Just some pseudo code is fine.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Codeception/Codeception/issues/3420#issuecomment-239128980, or mute the thread https://github.com/notifications/unsubscribe-auth/ABFb-MGWfRfx4FUlajVxq09bHdz64AFbks5qev6VgaJpZM4JgDbX .

bonsi commented 8 years ago

Just tested with a new route + test:

route/api.php:

Route::get('lara53', function() {
    return '5.3 works';
});

tests/api/SecureSessionCest.php:

public function test_laravel_53( ApiTester $I )
{
    $I->wantTo('Make sure the codeception laravel5 module works with 5.3');
    $I->visit('api/lara53')
       ->see('5.3 works');
}

result:

Time: 152 ms, Memory: 18.00MB

There was 1 error:

---------
1) SecureSessionCest: Make sure the codeception laravel5 module works with 5.3
 Test  tests/api/SecureSessionCest.php:test_laravel_53

  [TypeError] Argument 3 passed to Illuminate\Queue\Worker::__construct() must implement interface Illuminate\Contracts\Debug\ExceptionHandler, instance of Codeception\Lib\Connector\Laravel5\ExceptionHandlerDecorator given, called in /home/vagrant/dispatcher/vendor/laravel/framework/src/Illuminate/Queue/QueueServiceProvider.php on line 80
janhenkgerritsen commented 8 years ago

I am currently running into the same issue while upgrading the Laravel sample application for the 5.3 release, so I can investigate that a bit further. But I will probably just merge your PR, since I don't see any problems with it.

One thing from the code samples you posted, why are you using the visit method in a Codeception Cest class? That is a method from the test class that comes with Laravel, but it should not work with Codeception.

And thanks for your help and reporting the issue.

bonsi commented 8 years ago

Ah, old habits ;) visit should ofcourse be amOnPage.