ZF2 / PHPUnit: Mock a Zend/Db/Adapter/Adapter for further usage
Asked Answered
C

1

1

The goal: Unit test an InputFilter in Zend Framework 2.

The problem: A mocked DbAdapter is needed.

As I am relatively new to Unit Testing I just got started with mocking classes. After doing a lot of research I'm still unable to find a proper solution for my problem so here we go with my filter to start things off:

class ExampleFilter extends Inputfilter
{
    protected $dbAdapter;

    public function __construct(AdapterInterface $dbAdapter)
    {
        $this->dbAdapter = $dbAdapter;
    }

    public function init()
    {
        $this->add(
            [
                'name' => 'example_field',
                'required' => true,
                'filters' => [
                    ['name' => 'StringTrim'],
                    ['name' => 'StripTags'],
                ],
                'validators' => [
                    [
                        'name'    => 'Db\NoRecordExists',
                        'options' => [
                            'adapter' => $this->dbAdapter,
                            'table' => 'example_table',
                            'field' => 'example_field',
                        ],
                    ],
                ],
            ]
        );
    }
}

Without the need of an adapter, testing this filter would be rather easy. My problem is to create the Filter in my TestClass as seen here:

class ExampleFilterTest extends \PHPUnit_Framework_TestCase
{
    protected $exampleFilter;
    protected $mockDbAdapter;

    public function setUp()
    {
        $this->mockDbAdapter = $this->getMockBuilder('Zend\Db\Adapter')
            ->disableOriginalConstructor()
            ->getMock();
        $this->exampleFilter = new ExampleFilter($this->mockDbAdapter);
    }

}

When creating the filter like this the ExampleFilter class will end up saying that I did provide a wrong class to its constructor. It's receiving a mock object when expecting one of type Zend\Db\Adapter\Adapter.

I could create a real adapter of course but I want to avoid performing actual queries to the database as it is a unit test and this would go far beyond the border of my unit to test.

Can anyone tell me how I can achieve my goal of testing the filter with a mocked DbAdapter?

Clamant answered 11/12, 2015 at 13:48 Comment(5)
make sure the Zend\Db\Adapter class is loadable from the test. Also, you should mock the interface, not the class that will be provided in the real code. The test does not need to know what implementation will be used.Gearhart
I actually am mocking the interface, sorry for being confusing there. Zend/Db/Adapter is the interface while Zend/Db/Adapter/Adapter would be the Adapter class itself. The interface is also loadable. Problem still is to create the Filter class as it is dependent on the adapter interface.Clamant
The class is expecting an AdapterInterface, not the Zend\Db\Adapter you're sending.Gearhart
Completely correct. I instantly tried that after sending off my comment. Thanks for the hint :)Clamant
Do you want to write that as an answer? :PClamant
C
1

Well... As I was commenting on gontrollez hint I already smelled my mistake. I had to create a mock of 'Zend/Db/Adapter/AdapterInterface' instead of just '/Zend/Db/Adapter'.

Thanks for bringing me on the right path anyway gontrollez :)

Clamant answered 11/12, 2015 at 14:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.