这是以下代码示例
<?php
interface iFS
{
public function read();
public function write($data);
}
class MyClass
{
protected $_fs = null;
public function __construct(iFS $fs)
{
$this->_fs = $fs;
}
public function run(array $list)
{
foreach ($list as $elm)
{
$this->_fs->write($elm);
}
return $this->_fs->read();
}
}
class MyTests extends PHPUnit_Framework_TestCase
{
public function testFS()
{
$mock = $this->getMock('iFS');
$mock->expects($this->at(0))
->method('read')
->will($this->returnValue('tototatatiti'));
$c = new MyClass($mock);
$result = $c->run(array('toto', 'tata', 'titi'));
$this->assertEquals('tototatatiti', $result);
}
}
这绝对不是一个真实的案例,但它会让phpunit和($ index)功能发生一些奇怪的事情。
我的问题很简单,测试失败是正常的吗?
我明确地要求返回&#34; tototatatiti&#34;,但它永远不会发生......
何时
测试传递给绿色
有什么我不明白的吗?
编辑:
$模拟转&GT;期待($这 - &GT;在(3)) - &GT;方法(&#39;读&#39;) - &GT;将($这 - &GT;的returnValue(&#39; tototatatiti&#39;));
=&GT;将使测试通过绿色...
答案 0 :(得分:3)
根据PHPUnit source code我们有:
public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
{
$this->currentIndex++;
return $this->currentIndex == $this->sequenceIndex;
}
每次PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex
尝试匹配调用时,受保护变量$currentIndex
都会递增,因此您先写入的调用会使其变为0,然后它与{{1}不匹配}。
第二次调用read
导致值变为1,因此它也不匹配。
看起来它确实适用于整个对象,如果您需要确保以特定顺序发生一系列调用,这非常有用。
例如,假设read
方法仅被调用一次,您可以使用以下内容:
write
这确保$mock->expects($this->at(0))
->method('write');
$mock->expects($this->at(1))
->method('read')
->will($this->returnValue('tototatatiti'));
方法确实在write
方法之前调用。
答案 1 :(得分:0)
我认为phpunit at()功能对于模拟方法存在不同的返回结果是没有用的,如果模拟对象包含一些其他方法也是调用...
如果你想测试类似的东西:
$stub->expects($this->at(0))
->method('read')
->will($this->returnValue("toto"));
$stub->expects($this->at(1))
->method('read')
->will($this->returnValue("tata"));
你应该更好地使用像
这样的东西$stub->expects($this->exactly(2))
->method('read')
->will($this->onConsecutiveCalls("toto", "tata));