使用Mockery在PHP中模拟接口时出错

时间:2013-10-20 15:15:36

标签: php laravel mockery

我在PHP中使用Mockery模拟接口时遇到了一个问题(我正在使用laravel框架,但我不确定这是否相关。

我已经定义了一个接口

<?php namespace MyNamespace\SomeSubFolder;

interface MyInterface {

    public function method1();

}

我有一个类,在其中一个方法上键入接口...

<?php namespace MyNamespace\SomeSubFolder;

use MyNamespace\SomeSubFolder\MyInterface;

class MyClass {

    public function execute(MyInterface $interface)
    {
         //does some stuff here

    }
}

......我正在尝试测试MyClass。我创建了一个看起来像这样的测试:

public function testExecute()
{

    $mock = Mockery::mock('MyNamespace\SomeSubFolder\MyInterface');

    $mock->shouldReceive('method1')
         ->andReturn('foo');

    $myClass = new MyClass();

    $myClass->execute($mock);

}

当我运行测试时,我收到消息

'ErrorException:传递给MyClass :: execute的参数1必须是MyNamespace \ SomeSubFolder \ MyInterface的实例,Mockery_123465456的实例给出....'

我不知道为什么。

在测试中我尝试了以下内容:

$this->assertTrue(interface_exists('MyNamespace\SomeSubFolder\MyInterface'));

$this->assertTrue($mock instanceof MyInterface);

并且都返回true,所以看起来好像我已经创建了实现接口的实例,但是当我在类上调用该方法时它不同意。任何想法???

2 个答案:

答案 0 :(得分:11)

你应该在模拟声明和模拟声明中调用mock()方法。

$mock = Mockery::mock('MyNamespace\SomeSubFolder\MyInterface');

$mock->shouldReceive('method1')
     ->andReturn('foo')
     ->mock();

答案 1 :(得分:-1)

我认为问题出在PHP类加载上。您的测试文件中没有“MyNamespace \ SomeSubFolder \ MyInterface”类。

您需要修改您的composer.json以自动加载该命名空间,或者您需要在测试顶部使用require_once('path / to / file / containing / namespace / MyInterface.php')。

虽然,当你尝试使用interface_exists时,它似乎已经过去了。当你嘲笑它时,也可能是你拼错了你的命名空间类。我也犯了这个错误。

在任何情况下, Mockery都无法看到该类存在,所以它只是发明了一个。

您能提供完整的测试资源吗?