使用 $mock->expects($this->at(...)) 时 PHPUnit "Mocked method does not exist."

标签 php unit-testing mocking phpunit

我遇到了一个关于 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));
    }

    ...
}

当我运行测试时,我得到:

Expectation failed for method name is equal to <string:exists> when invoked at sequence index 1.
Mocked method does not exist.

如果我删除第二个匹配器,我不会收到错误。

有人遇到过这个吗?

谢谢!

最佳答案

问题最终变成了我如何理解“at”匹配器的工作方式。另外,我的示例在我的单元测试中并不是逐字逐句的。我认为“at”匹配器计数器在每个查询的基础上工作,而实际上它在每个对象实例的基础上工作。

例子:

class MyClass {

    public function exists($foo) {
        return false;
    }

    public function find($foo) {
        return $foo;
    }
}

不正确:

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

}

正确:

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

}

关于使用 $mock->expects($this->at(...)) 时 PHPUnit "Mocked method does not exist.",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3367513/

相关文章:

unit-testing - iPhone单元测试OCMock,如何模拟只读变量?

javascript - 根据 json 数组值选择 html 复选框

javascript - jQuery 自动完成列表未显示

php - Laravel 5.1 用户输入文本中的链接/可点击链接

unit-testing - 在使用 phantomjs 和 jasmine 进行单元测试时拍摄网页快照

java - Google Task API 的单元测试

Python模拟类实例变量

javascript - JQuery-AJAX 表单提交但重新加载页面,更改 url

python - 如何阻止 Python unittest 打印测试文档字符串?

Node.js Mocha 单元测试错误 re : Mongoose mocks with Mockgoose, "Error setting TTL index on collection : sessions"