php - 支持链接方法的模拟对象

标签 php unit-testing mocking phpunit

我想知道是否有一种相当简洁的方法来模拟支持方法链的对象...例如,数据库查询对象可能有一个如下所示的方法调用:

$result = $database->select('my_table')->where(array('my_field'=>'a_value'))->limit(1)->execute();

如果我必须模拟两个不同的选择查询以便它们返回不同的结果,问题就来了。有什么想法吗?

这是专门针对 PHPUnit 的,但其他单元测试框架的经验会有所帮助。

最佳答案

我不确定这是你要找的,所以请发表评论:

class StubTest extends PHPUnit_Framework_TestCase
{
    public function testChainingStub()
    {
        // Creating the stub with the methods to be called
        $stub = $this->getMock('Zend_Db_Select', array(
            'select', 'where', 'limit', 'execute'
        ), array(), '', FALSE);

        // telling the stub to return a certain result on execute
        $stub->expects($this->any())
             ->method('execute')
             ->will($this->returnValue('expected result'));

        // telling the stub to return itself on any other calls
        $stub->expects($this->any())
             ->method($this->anything())
             ->will($this->returnValue($stub));

        // testing that we can chain the stub
        $this->assertSame(
            'expected result',
            $stub->select('my_table')
                 ->where(array('my_field'=>'a_value'))
                 ->limit(1)
                 ->execute()
        );
    }
}

您可以将其与期望相结合:

class StubTest extends PHPUnit_Framework_TestCase
{
    public function testChainingStub()
    {
        // Creating the stub with the methods to be called
        $stub = $this->getMock('Zend_Db_Select', array(
            'select', 'where', 'limit', 'execute'
        ), array(), '', FALSE);

        // overwriting stub to return something when execute is called
        $stub->expects($this->exactly(1))
             ->method('execute')
             ->will($this->returnValue('expected result'));

        $stub->expects($this->exactly(1))
             ->method('limit')
             ->with($this->equalTo(1))
             ->will($this->returnValue($stub));

        $stub->expects($this->exactly(1))
             ->method('where')
             ->with($this->equalTo(array('my_field'=>'a_value')))
             ->will($this->returnValue($stub));

        $stub->expects($this->exactly(1))
             ->method('select')
             ->with($this->equalTo('my_table'))
             ->will($this->returnValue($stub));

        // testing that we can chain the stub
        $this->assertSame(
            'expected result',
            $stub->select('my_table')
                 ->where(array('my_field'=>'a_value'))
                 ->limit(1)
                 ->execute()
        );
    }
}

关于php - 支持链接方法的模拟对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4232763/

相关文章:

unit-testing - Go:如何为多个包运行测试?

php - Symfony2/Doctrine2 Oracle 游标问题

php - 保持 css 下拉菜单项用 php 突出显示

java - 从单元测试中设置依赖关系的最佳策略?

unit-testing - 你如何测试依赖注入(inject)?

c# - 模拟任务.延迟

python - 在 Python 中模拟无限生成器

ruby-on-rails-3 - Rspec 2 和 Rails 3 stub /模拟

php - 通过网站上的 Flash 流式传输实时视频

php - 将一个巨大的 html 文件转换为 php 变量/echo