dousong5492 2010-11-20 12:43 采纳率: 100%
浏览 31
已采纳

模拟支持链接方法的对象

I'm wondering if there's a fairly concise way of mocking objects which support chaining of methods... so for example, a database query object might have a method call that looks like this:

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

The problem comes if I have to mock two different select queries so that they return different results. Any ideas?

This is specifically about PHPUnit, but experiences from other unit testing frameworks will help.

  • 写回答

3条回答 默认 最新

  • dsfvsdfv23599 2010-11-20 14:50
    关注

    I am not sure this is what you are looking for, so please leave a comment:

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

    You can combine this with expectations:

    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()
            );
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥50 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 latex怎么处理论文引理引用参考文献
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?