PHPUnit - 模拟 PDO 语句获取
仍在测试映射器类的过程中,我需要模拟 PDO。 但现在我遇到了无限循环问题:
$arrResult = array(
array('id'=>10, 'name'=>'abc'),
array('id'=>11, 'name'=>'def'),
array('id'=>12, 'name'=>'ghi')
);
$STMTstub->expects($this->any())
->method('fetch')
->will($this->returnValue($arrResult));
$PDOstub = $this->getMock('mockPDO');
$PDOstub->expects($this->any())
->method('prepare')
->will($this->returnValue($STMTstub));
当然,当测试 1 fetch 或 fetchAll 时,该代码是完美的。但是当涉及到多次获取时,就会发生无限循环。就像在这种情况下:
while($arr = $stmt->fetch()){
//...
}
所以我希望 fetch() 循环遍历所有 $arrResult 并一一返回子数组以模拟真正的 fetch() 行为。我可以“挂钩一个函数”来这样做吗?
Still in the process of testing a mapper class, I need to mock PDO.
But now I ran into an infinite loop problem:
$arrResult = array(
array('id'=>10, 'name'=>'abc'),
array('id'=>11, 'name'=>'def'),
array('id'=>12, 'name'=>'ghi')
);
$STMTstub->expects($this->any())
->method('fetch')
->will($this->returnValue($arrResult));
$PDOstub = $this->getMock('mockPDO');
$PDOstub->expects($this->any())
->method('prepare')
->will($this->returnValue($STMTstub));
Of course, that code is perfect when it come to test 1 fetch or a fetchAll. But when it come to multiple fetch, the infinite loop happen. Like in that case:
while($arr = $stmt->fetch()){
//...
}
So I'd like the fetch() to loop through all the $arrResult and return the sub-array one by one to simulate the true fetch() behavior. Can I "hook a function" to do so or something ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您有两种选择:
at()
对返回值进行排序,或者returnCallback()
调用一个函数通过多次调用产生所需的结果。使用
at()
非常简单。您传入 PHPUnit 与调用相匹配的索引,以选择要触发的期望。请注意,传递给at()
的索引涵盖对模拟的所有调用。如果$STMTstub
将在fetch()
调用之间接收其他模拟调用,您需要相应地调整索引。使用 returnCallback() 需要更多的脚手架,但它避免了所有索引恶作剧。 ;)
yieldResults()
是通用的,只要您为每个结果集指定一个唯一的$name
,它就可以处理任意数量的同时结果集。如果您不使用带有回调的 PHP 5.3,请将对yieldResults()
的调用包装在另一个函数中,该函数的名称将传递给returnCallback()
。我还没有测试过,但看起来相当不错。You have two options:
at()
to order the returned values, orreturnCallback()
to call a function that yields the desired results across multiple calls.Using
at()
is pretty straight-forward. You pass in an index that PHPUnit matches up against the calls to pick which expectation to fire. Note that the index passed toat()
is across all calls to the mock. If$STMTstub
will receive other mocked calls between the calls tofetch()
, you'll need to adjust the indexes accordingly.Using
returnCallback()
will require a bit more scaffolding, but it avoids all the index shenanigans. ;)yieldResults()
is generic and will work with any number of simultaneous result sets as long as you give each a unique$name
. If you're not using PHP 5.3 with callbacks, wrap the call toyieldResults()
inside another function whose name you pass toreturnCallback()
. I haven't tested it out, but it seems fairly sound.