Codeception / module-mezzio

Codeception Module for Mezzio framework (formerly known as Zend Expressive)
MIT License
1 stars 2 forks source link

ZendExpressive module fails when trying to use DataFactory with recreateApplicationBetweenTests set to true #7

Open pawelryznar opened 5 years ago

pawelryznar commented 5 years ago

What are you trying to achieve?

I'm trying to use use FactoryMuffin for tests in my Zend Expressive application. With default setting recreateApplicationBetweenTests: true for ZendExpressive module tests don't work. I'm getting an exception. Changing config to recreateApplicationBetweenTests: false helps but I need to use recreateApplicationBetweenTests: true.

What do you get instead?

php vendor/bin/codecept run tests/api/Stores/CreateViewCest.php -vvv
Codeception PHP Testing Framework v3.1.0
Powered by PHPUnit 8.3.4 by Sebastian Bergmann and contributors.
Running with seed:

[Seed] 1069952343

  [Connecting To Db] {"config":{"populate":false,"cleanup":false,"reconnect":false,"waitlock":0,"dump":"tools/migration/giftcard_structure.sql","populator":null,"dsn":"mysql:host=127.0.0.1;dbname=test_giftcard_local;port=32768","user":"api_user","password":"api_user_pwd"},"options":[]}
  [Db] Connected to default test_giftcard_local
PHP Fatal error:  Uncaught Error: Call to a member function has() on null in /Users/local/Workspace/proj/vendor/codeception/codeception/src/Codeception/Module/ZendExpressive.php:94
Stack trace:
#0 /Users/local/Workspace/proj/vendor/codeception/codeception/src/Codeception/Module/Doctrine2.php(222): Codeception\Module\ZendExpressive->_getEntityManager()
Codeception/Codeception#1 /Users/local/Workspace/proj/vendor/codeception/codeception/src/Codeception/Module/Doctrine2.php(1011): Codeception\Module\Doctrine2->retrieveEntityManager()
Codeception/Codeception#2 /Users/local/Workspace/proj/vendor/codeception/codeception/src/Codeception/Module/DataFactory.php(178): Codeception\Module\Doctrine2->_getEntityManager()
Codeception/Codeception#3 /Users/local/Workspace/proj/vendor/codeception/codeception/src/Codeception/Module/DataFactory.php(158): Codeception\Module\DataFactory->getStore()
Codeception/Codeception#4 /Users/local/Workspace/proj/vendor/codeception/codeception/src/Codeception/Module/ZendExpressive.php on line 94

Details

class_name: ApiTester
modules:
  enabled:
    - \Tests\Helper\Api
    - Asserts
    - Db
    - REST
    - DataFactory
  config:
    \Tests\Helper\Api:
      environment_file: .env.testing
      disable_exception_handling: false
      run_database_seeder: false
      cleanup: false
      recreateApplicationBetweenTests: true
    REST:
      depends: \Tests\Helper\Api
      part: Json
    DataFactory:
      factories: tests/_support/factories
      depends: Doctrine2
      cleanup: false
    Doctrine2:
      depends: \Tests\Helper\Api
Naktibalda commented 5 years ago

_getEntityManager method is called in _beforeSuite when it isn't initialized yet. I think that it should be enough to add this code to _getEntityManager:

if (!isset($this->container)) {
    $this->container   = $this->client->getContainer();
}

It would be a completely different story to get DataFactory and Doctrine modules working with recreateApplicationBetweenRequests, because it is necessary to make Doctrine instance persist between requests. ZF2 module does it like this, ZendExpressive module would have to work with all 3 supported service managers.

pawelryznar commented 5 years ago

No that doesn't work. I tried it already and then realised that in vendor/codeception/codeception/src/Codeception/Module/ZendExpressive.php

there are deprecation comments for two properties

    /**
     * @var \Interop\Container\ContainerInterface
     * @deprecated Doesn't work as expected if Application is recreated between requests
     */
    public $container;

    /**
     * @var \Zend\Expressive\Application
     * @deprecated Doesn't work as expected if Application is recreated between requests
     */
    public $application;
Naktibalda commented 5 years ago

deprecated tags are for direct access to these properties, I will make them private in the next major version.

pawelryznar commented 5 years ago

This causes more problems than I thought, because in one of the middlewares we add Doctrine filters. So all tests are working when executed separately, but when run all at once, only first one is passing.