We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

phpunit tests failing with "invalid superglobal" exception

I recently updated phalcon on a project that I hadn't looked at for a while (running on 3.0) and now the unit tests which ran before are failing with a "Exception: Invalid superglobal" error.

I'm extending the incubator's UnitTestCase and adding some more services to the DI. The DI is visible and accessible in the unit tests but doesn't exist in the code the tests are calling.

So for example, I would be testing a class which extends Component which would use $this->session to get the session service. During the test however that variable does not exist resulting in the invalid superglobal error.

I'm using a test helper file as described in the docs to load up a config, register namespaces and include the incubator. All the classes are included and executed fine; the only issue is the lack of those services in the app code extending Component...

Thanks!

Is the session being started?



2.1k

Yah, here's part of the code of the test class' setUp() function:


$di->setShared('session', function () {
      $session = new SessionAdapter();
      $session->start();
      return $session;
    });
$this->setDI($di);

Is the session being started?



2.1k

I got it to work but I still don't know why this fixes it.

@ChangePlaces, your question made me doublecheck my assumption about the session so I found that despite doing $session->start, checking if $session->isStarted() in the test setup returned false. There is no indication that anything failed so I don't know why it wouldn't have started. (this is the downside of not being able to trace through phalcon's code)

Next I tried registering the session adapter in the default DI in the helper file that phpunit uses to bootsrapt the tests (TestHelper.php).

$di = new FactoryDefault();

$di->setShared('session', function () {
  $session = new SessionAdapter();
  $session->start();
  return $session;
});

This still didn't do it, so I doublechecked what's going on by adding:

$session = $di->get('session')->isStarted();

Suddenly $session was true and my tests were working.

I still had to register the session in setUp() or my code didn't have the session global even though the session technically failed to start there.

I have no idea why it the session can't start in the test setup or why it needs to be asked whether it's alive before it is in TestHelper.php. This is in php 7.0.7 btw and I know the tests used to work on php 5 (though it may have been an ealier version of phalcon as well.



1.8k

A workaround for me was adding stderr="true" to my phpunit.xml.

However I'm migrating my tests to a Codeception testsuite in which the above no longer works. I'm getting the following error:

1) AuthTest: Auth by valid id
 Test  tests/unit/AuthTest.php:authByValidId

  [Exception] Invalid superglobal  

/Users/daan/Sites/danq-cms/app/modules/admin/library/auth/Auth.php:266
/Users/daan/Sites/danq-cms/tests/unit/AuthTest.php:185
/Users/daan/Sites/danq-cms/vendor/phpunit/phpunit/src/Framework/TestCase.php:1145
/Users/daan/Sites/danq-cms/vendor/phpunit/phpunit/src/Framework/TestCase.php:840
/Users/daan/Sites/danq-cms/vendor/phpunit/phpunit/src/Framework/TestResult.php:645
/Users/daan/Sites/danq-cms/vendor/phpunit/phpunit/src/Framework/TestCase.php:798
/Users/daan/Sites/danq-cms/vendor/phpunit/phpunit/src/Framework/TestSuite.php:776
/Users/daan/Sites/danq-cms/vendor/codeception/phpunit-wrapper/src/Runner.php:114
/Users/daan/Sites/danq-cms/vendor/codeception/codeception/src/Codeception/SuiteManager.php:157
/Users/daan/Sites/danq-cms/vendor/codeception/codeception/src/Codeception/Codecept.php:189
/Users/daan/Sites/danq-cms/vendor/codeception/codeception/src/Codeception/Codecept.php:158
/Users/daan/Sites/danq-cms/vendor/codeception/codeception/src/Codeception/Command/Run.php:466
/Users/daan/Sites/danq-cms/vendor/codeception/codeception/src/Codeception/Command/Run.php:361
/Users/daan/Sites/danq-cms/vendor/symfony/console/Command/Command.php:252
/Users/daan/Sites/danq-cms/vendor/symfony/console/Application.php:865
/Users/daan/Sites/danq-cms/vendor/symfony/console/Application.php:241
/Users/daan/Sites/danq-cms/vendor/symfony/console/Application.php:143
/Users/daan/Sites/danq-cms/vendor/codeception/codeception/src/Codeception/Application.php:108
/Users/daan/Sites/danq-cms/vendor/codeception/codeception/package/bin:37
phar:///usr/local/bin/codecept/autoload.php:12
/usr/local/bin/codecept:5

It fails on setting a session variable like so: $this->session->set('key', 'value');.

Any of you have a clue what is going wrong, I can't seem to find any info about this issue.



1.8k

Adding backup_globals: false to the codeception.yml seems to fix my issues..