Solved thread

This post is marked as solved. If you think the information contained on this thread must be part of the official documentation, please contribute submitting a pull request to its repository.

PhpUnit and Phalcon Models

Hello to everyone, i just started to work with phalcon this weekend. I wanted to set a simple Authentication Script. I started to create some Models and there relations. After that worked, i startet to write tests for it.

i followed the tutorial here https://docs.phalconphp.com/en/latest/reference/unit-testing.html. Worked so far but then i had a problem that i only could call the model in the first test method. I did a little bit of research and found this solution for it. https://forum.phalconphp.com/discussion/6538/phpunit-di-only-available-in-first-testcase So i put the DB config in the Bootstrap

<?php

use Phalcon\DI;
use Phalcon\DI\FactoryDefault;

ini_set('display_errors',1);
error_reporting(E_ALL);
date_default_timezone_set('Europe/Vienna');

define('ROOT_PATH', __DIR__);
define('PATH_LIBRARY', __DIR__ . '/../src/library/');
define('PATH_SERVICES', __DIR__ . '/../src/services/');
define('PATH_RESOURCES', __DIR__ . '/../src/resources/');
define('PATH_ENTITIES', __DIR__ . '/../src/entities/');

set_include_path(
    ROOT_PATH . PATH_SEPARATOR . get_include_path()
);

// Required for phalcon/incubator
include __DIR__ . "/../vendor/autoload.php";

// Use the application autoloader to autoload the classes
// Autoload the dependencies found in composer
$loader = new \Phalcon\Loader();

$loader->registerNamespaces(array(
    'PaPhalconAuth\Entities' => PATH_ENTITIES,
));
$loader->registerDirs(
    array(
        ROOT_PATH,
    )
);

$loader->register();

$di = new FactoryDefault();
DI::reset();


$config = array(
    'adapter'     => 'Mysql',
    'host'        => 'localhost',
    'username'    => 'root',
    'password'    => 'root',
    'dbname'      => 'auth',
    'charset'     => 'utf8',
);

// Add any needed services to the DI here
$di->set('db', function () use ($config) {
    $adapter = $config['adapter'];
    unset($config['adapter']);

    $class = 'Phalcon\Db\Adapter\Pdo\\' . $adapter;

    return new $class($config);
});

DI::setDefault($di);

worked in almost all cases but in some cases it didnĀ“t and i received again the message "Service 'db' wasn't found in the dependency injection container". That happens when i am for e.g calling findFirst. the find() function is working fine but not findFirst()

/**
 * @covers PaPhalconAuth\Entities\AuthUserRoles::find
 * @covers PaPhalconAuth\Entities\AuthUserRoles::findFirst
 */
public function testAuthUserRolesFindFirst()
{
  $userRoles = new AuthUserRoles();
  $this->assertEquals($userRoles->find()->getFirst(), $userRoles->findFirst());
  $this->assertEquals(4,$userRoles->find()->count());
}

I could solve this problem, when i am also putting the DB DI config in the "UnitTestCase.php" file.

<?php
use Phalcon\DI;
use Phalcon\Test\UnitTestCase as PhalconTestCase;

abstract class UnitTestCase extends PhalconTestCase
{
    /**
     * @var \Voice\Cache
     */
    protected $_cache;

    /**
     * @var \Phalcon\Config
     */
    protected $_config;

    /**
     * @var bool
     */
    private $_loaded = false;

    public function setUp(Phalcon\DiInterface $di = NULL, Phalcon\Config $config = NULL)
    {
        // Load any additional services that might be required during testing
        $di = new \Phalcon\Di\FactoryDefault;

        // Get any DI components here. If you have a config, be sure to pass it to the parent
        $config= include '../src/config/config.php';
        $di->setShared('db', function () use ($config) {
            $dbConfig = $config->database->toArray();
            $adapter = $dbConfig['adapter'];
            unset($dbConfig['adapter']);

            $class = 'Phalcon\Db\Adapter\Pdo\\' . $adapter;

            return new $class($dbConfig);
        });

        parent::setUp($di);

        $this->_loaded = true;
    }

    /**
     * Check if the test case is setup properly
     *
     * @throws \PHPUnit_Framework_IncompleteTestError;
     */
    public function __destruct()
    {
        if (!$this->_loaded) {
            throw new \PHPUnit_Framework_IncompleteTestError('Please run parent::setUp().');
        }
    }
}

So i have it now in the bootstrap and in the unitTestCase file. When i am deleting the code out of one, then it is not working anymore. I think i have a major issue with the Test setup because of the tearDown with DI.

Also when i am just creating a second Test file now with a simple equal test 0=0, the whole first file with the Models is not working anymore and i get the message:

Phalcon\Mvc\Model\Exception : A dependency injector container is required to obtain the services related to the ORM

So i hope someone has the time to help me. i would be really thankful. The whole source code is on gitHub https://github.com/patrickascher/PaPhalconAuth/tree/master/tests

Thanks Pat

thanks, that really helped me