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

MVC Models - replacing Phalcon\Db\Adapter\Pdo\Mysql with a stub

Hi all,

I'm playing with Phalcon application unit testing.

I decided to write tests for my model Robot and stub out actual DB adapter, so I could run test without worrying about working database instance.

When I'm executing

    $robot = Robot::findFirst(1);

I want to populate object properties with contents of PHP array:

    [
        'id' => 1,
        'name' => 'Charles',
        'role' => 'Cleaner'
    ]

I do not want to stub Robot itself. I only want to eliminate database access.

My first attempt was this:

    $this->di->set('db', function(){

        $stub = $this->getMockBuilder('Phalcon\Db\Adapter\Pdo\Mysql')
            ->disableOriginalConstructor()
            ->getMock();

        $stub->expects($this->at(0))
             ->method('tableExists')
             ->will($this->returnCallback(function(){
                return true;
             }));

        $stub->expects($this->at(1))
             ->method('getMetadata')
             ->will($this->returnCallback(function(){
                  // This was where I realized that I have to stub out
                  // all calls made internally by Phalcon\Mvc\Model
             }));

        return $stub;
    });

And as I wrote in the comments above - the realization that I'd have to return proper output from ALL internal calls of Phalcon\MVC\Model made me think that it is quite difficult to eliminate the database component.

Is there any alternative approach to the problem?

Thanks, Temuri



98.9k

MetaData is a different service than the Database service, you probably need to mock that service too. https://docs.phalcon.io/en/latest/reference/models.html#models-meta-data



51.3k

@Phalcon That's the thing. If I don't need DB, I don't need metadata. There should be a way to short-circuit all that stuff, set all of $this->{property} and get on with loading events..



98.9k

@temuri416 I've put an example for this, I've been having the same issue for a while but I've managed to figure it out, I think: https://www.rami.me.uk/how-to-unit-test-code-with-phalcon-mvc-models/

@silverbadge, in your example find method of a model returns no rows with any data at dataProvider. Is there a way to fix it?