ZF2 / PHPUnit:模拟 Zend/Db/Adapter/Adapter 以供进一步使用

Posted

技术标签:

【中文标题】ZF2 / PHPUnit:模拟 Zend/Db/Adapter/Adapter 以供进一步使用【英文标题】:ZF2 / PHPUnit: Mock a Zend/Db/Adapter/Adapter for further usage 【发布时间】:2016-03-17 10:56:13 【问题描述】:

目标:在 Zend Framework 2 中对 InputFilter 进行单元测试。

问题:需要一个模拟的 DbAdapter。

由于我对单元测试比较陌生,所以我刚刚开始使用模拟类。经过大量研究后,我仍然无法为我的问题找到合适的解决方案,所以我们在这里使用我的过滤器来开始:

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',
                        ],
                    ],
                ],
            ]
        );
    

无需适配器,测试此过滤器将相当容易。我的问题是在我的 TestClass 中创建过滤器,如下所示:

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);
    

当像这样创建过滤器时,ExampleFilter 类最终会说我确实为它的构造函数提供了一个错误的类。当期望 Zend\Db\Adapter\Adapter 类型之一时,它正在接收一个模拟对象。

我当然可以创建一个真正的适配器,但我想避免对数据库执行实际查询,因为它是一个单元测试,这将远远超出我要测试的单元的边界。

谁能告诉我如何实现使用模拟 DbAdapter 测试过滤器的目标?

【问题讨论】:

确保 Zend\Db\Adapter 类可以从测试中加载。此外,您应该模拟接口,而不是真实代码中提供的类。测试不需要知道将使用什么实现。 我实际上是在嘲笑界面,很抱歉在那里造成混淆。 Zend/Db/Adapter 是接口,而 Zend/Db/Adapter/Adapter 是 Adapter 类本身。该界面也是可加载的。问题仍然是创建过滤器类,因为它依赖于适配器接口。 课程期待的是AdapterInterface,而不是您发送的Zend\Db\Adapter 完全正确。发表评论后,我立即尝试了这一点。感谢您的提示:) 你想把它写成答案吗? :P 【参考方案1】:

嗯...当我在评论 gontrollez 提示时,我已经嗅到了我的错误。我必须创建一个“Zend/Db/Adapter/AdapterInterface”的模拟,而不仅仅是“/Zend/Db/Adapter”。

无论如何,谢谢你让我走上正确的道路 :)

【讨论】:

以上是关于ZF2 / PHPUnit:模拟 Zend/Db/Adapter/Adapter 以供进一步使用的主要内容,如果未能解决你的问题,请参考以下文章

ZF2 - \Zend\Db\Adapter\Platform::getQuoteIdentifierSymbol()

ZF2中的Zend Db如何控制事务?

ZF2 - 使用 Ajax 填充选择

PHPUnit:模拟除ZendFramework2 Controller中的一个函数之外的所有函数

如何将 ZF2 单元/应用程序模块测试合并到单个调用中?

PHPUnit错误未定义变量