rr.*_*rr. 38 php phpunit unit-testing mocking
我遇到了PHPUnit模拟对象的一个奇怪问题.我有一个应该被调用两次的方法,所以我使用的是"at"匹配器.这是第一次调用该方法,但由于某种原因,第二次调用它时,我得到"模拟方法不存在".我之前使用过"at"匹配器并且从未遇到过这种情况.
我的代码看起来像:
class MyTest extends PHPUnit_Framework_TestCase
{
...
public function testThis()
{
$mock = $this->getMock('MyClass', array('exists', 'another_method', '...'));
$mock->expects($this->at(0))
->method('exists')
->with($this->equalTo('foo'))
->will($this->returnValue(true));
$mock->expects($this->at(1))
->method('exists')
->with($this->equalTo('bar'))
->will($this->returnValue(false));
}
...
}
Run Code Online (Sandbox Code Playgroud)
当我运行测试时,我得到:
Expectation failed for method name is equal to <string:exists> when invoked at sequence index 1.
Mocked method does not exist.
Run Code Online (Sandbox Code Playgroud)
如果我删除第二个匹配器,我不会收到错误.
有没有人遇到过这个?
谢谢!
rr.*_*rr. 42
问题最终与我如何理解"at"匹配器的工作方式有关.另外,我的例子并非逐字逐句地在我的单元测试中.我认为"at"匹配器计数器在每个查询的基础上工作,它真正适用于每个对象实例.
例:
class MyClass {
public function exists($foo) {
return false;
}
public function find($foo) {
return $foo;
}
}
Run Code Online (Sandbox Code Playgroud)
不正确:
class MyTest extends PHPUnit_Framework_TestCase
{
public function testThis()
{
$mock = $this->getMock('MyClass');
$mock->expects($this->at(0))
->method('exists')
->with($this->equalTo('foo'))
->will($this->returnValue(true));
$mock->expects($this->at(0))
->method('find')
->with($this->equalTo('foo'))
->will($this->returnValue('foo'));
$mock->expects($this->at(1))
->method('exists')
->with($this->equalTo('bar'))
->will($this->returnValue(false));
$this->assertTrue($mock->exists("foo"));
$this->assertEquals('foo', $mock->find('foo'));
$this->assertFalse($mock->exists("bar"));
}
}
Run Code Online (Sandbox Code Playgroud)
正确:
class MyTest extends PHPUnit_Framework_TestCase
{
public function testThis()
{
$mock = $this->getMock('MyClass');
$mock->expects($this->at(0))
->method('exists')
->with($this->equalTo('foo'))
->will($this->returnValue(true));
$mock->expects($this->at(1))
->method('find')
->with($this->equalTo('foo'))
->will($this->returnValue('foo'));
$mock->expects($this->at(2))
->method('exists')
->with($this->equalTo('bar'))
->will($this->returnValue(false));
$this->assertTrue($mock->exists("foo"));
$this->assertEquals('foo', $mock->find('foo'));
$this->assertFalse($mock->exists("bar"));
}
}
Run Code Online (Sandbox Code Playgroud)
yvo*_*yer 17
仅供参考,我不确定它是否相关,但我遇到了同样的事情,但没有使用$this->at()方法,对我来说这是$this->never()方法.
这引起了错误
$mock->expects($this->never())
->method('exists')
->with('arg');
Run Code Online (Sandbox Code Playgroud)
这修复了错误
$mock->expects($this->never())
->method('exists');
Run Code Online (Sandbox Code Playgroud)
使用该$this->exactly(0)方法时它做了同样的事情.
希望这能有所帮助.