We are moving our forum in GitHub Discussions. For questions about Phalcon v3/v4 you can visit here and for Phalcon v5 here.

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.phalcon.io/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.phalcon.io/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