如何模拟Laravel的雄辩访问者属性

时间:2015-06-05 10:53:54

标签: php laravel-4 mockery

我在Laravel 4应用程序中实现了单元测试,但我仍然坚持使用模拟访问器属性。

我有一个Eloquent模型,其中包含Accessor属性。我试图模拟这个模型,并在调用此访问器属性时返回一个值。但我无法找到任何解决方案来使其发挥作用。

我的超级简单用户类。

class User extends Eloquent {
    public function getFullNameAttribute() {
        return $this->first_name . ' ' . $this->last_name;
    }
}

我尝试了以下内容:

$user_mock = m::mock('MyApp\Models\User');

$user_mock->shouldReceive('__get')->with('full_name')->andReturn('John Snow'); // doesn't work
$user_mock->shouldReceive('getAttribute')->with('full_name')->andReturn('John Snow'); // doesn't work
$user_mock->shouldReceive('getFullNameAttribute')->andReturn('John Snow'); // doesn't work

echo $user_mock->full_name; // --> " "

我刚回来一个空的空间,表明仍在调用原始函数。

2 个答案:

答案 0 :(得分:2)

尽量不要嘲笑雄辩的模特。这是"嘲笑你不拥有的类型的例子。如果Laravel在新版本中更改了雄辩的内部结构,并且您在单元测试中嘲笑了它们,那么您的测试可能会提供误报。

另外我觉得尝试嘲笑他们很奇怪。你失去了这些实体映射到现实世界的想法,而它是需要单独测试的业务逻辑组件(依赖模拟)。

使用访问器时,我发现将它包装在另一个抽象中是有帮助的,例如在Repository层中:

public function getFirstNameAttribute()
{
     return app(UserRepository::class)->getFirstName($this);
}

我发现访问器使客户端代码极具可读性。这是完全可测试的,并且与数据库的整个交互是可模拟的,如果您有数千个测试,这可能有助于减少开销。

答案 1 :(得分:-2)

看看Mockery的文档,看起来它不支持模拟魔术方法。您基本上只需要使用普通赋值来设置属性:

$user_mock = m::mock('MyApp\Models\User');
$user_mock->first_name = 'John Snow';

Mockery docs