yiisoft / yii2

Yii 2: The Fast, Secure and Professional PHP Framework
http://www.yiiframework.com
BSD 3-Clause "New" or "Revised" License
14.24k stars 6.9k forks source link

REST API testing with Codeception doesn't handle Exceptions #16965

Open tahpot opened 5 years ago

tahpot commented 5 years ago

What steps will reproduce the problem?

Create a REST API test that calls an action that throws an Exception.

This is the test:

<?php
namespace tests\api\controllers;

use \Codeception\Util\HttpCode;

class SiteCest
{
    public function testApiDisabled(\ApiTester $I)
    {
        $api = \Yii::$app->clientApi;
        $api->enabled = false;

        $I->sendGET('/site'); // throws exception, rather than being handled by Yii and generating a valid JSON response
        $I->seeResponseCodeIs(HttpCode::INTERNAL_SERVER_ERROR);
        $I->seeResponseIsJson();
    }

}

What is the expected result?

Expect Yii2 to catch the Exception via ErrorHandler and still generate a valid JSON response that can be checked using Codeception.

For example $I->seeResponseCodeIs(HttpCode::INTERNAL_SERVER_ERROR); should return true, but the HTTP code seen by Codeception is null.

What do you get instead?

The Exception propagates up to Codeception which automatically fails the test and also causes the following tests to not have correct information.

Additional info

Q A
Yii version 2.0.15.1
PHP version 7.2.11
Operating system Amazon 2 AMI

@samdark

samdark commented 5 years ago

Would you please try dev-master? Also it's a good idea to upgrade Codeception, there were fixes.

tahpot commented 5 years ago

Thanks.

I upgraded Yii2 to dev-master and Codeception is v2.5.1 and the issue remains.

joshgagnon commented 5 years ago

See here: https://github.com/Codeception/Codeception/blob/2.5/src/Codeception/Lib/Connector/Yii2.php#L336

Your exception must be an instance of HttpException or it will be passed up to codeception.

tahpot commented 5 years ago

Thanks @joshgagnon

Isn't the flow supposed to be this?

  1. Any exception raised in application code
  2. Yii ErrorHandler catches exception, modifies output and raises HTTP 500 Exception
  3. Codeception catches the HTTP 500 Exception
rob006 commented 5 years ago

Isn't the flow supposed to be this? /.../ Yii ErrorHandler catches exception, modifies output and raises HTTP 500 Exception

Normally it is. But Codeception explicitly disables Yii error handling for non-http exceptions.

I don't think that there is anything to do at Yii side, this behavior comes from Codeception. I also think that current behavior is correct - usually you expect that your code will work and converting all exceptions into HTTP 500 response will make debugging much harder.