【问题标题】:Laravel 5 mock a Eloquent modelLaravel 5 模拟 Eloquent 模型
【发布时间】:2015-03-12 12:31:07
【问题描述】:

我正在测试我的一个控制器,无论我尝试什么,我都会收到 all() 函数不存在的错误。

Static method Mockery_1_App_Models_User::all() does not exist on this mock object

我的测试方法:

/**
 * Test index page
 * @return void
 */
public function testIndexAsUser()
{
    $this->beUser();

    // The method calls the mock objects should receive
    $this->user->shouldReceive('all')->once()->andReturn([]);

    // Call index page
    $response = $this->call('GET', 'users');

    // Assertions
    $this->assertResponseOk();
    $this->assertViewHas('user');
    $this->assertViewNameIs('users.show');
}

我的嘲讽方法:

/**
 * Mock a class
 * @param  string $class
 * @return Mockery
 */
public function mock($class)
{
    $mock = Mockery::mock('Eloquent', $class);

    app()->instance($class, $mock);

    return $mock;
}

我的实际控制器方法:

/**
 * Show all users
 * @return Response
 */
public function getIndex()
{
    $users = $this->user->all();

    return view('users.index');
}

我在我的模拟对象中使用了错误的 Eloquent 类吗?从 Laravel 5 开始,模型不是指 Eloquent,而是指 Illuminate\Database\Eloquent\Model,但我也试过了。

【问题讨论】:

  • 这很可能与 Laravel 5 尚未进入 Beta 版这一事实有关 - 并且 Laravel 5 的“测试”功能尚未完成。在 Taylor 完成对 L5 的所有测试支持之前,我不会花太多时间在上面
  • 你试过Mockery::mock('Model', $class)Mockery::mock('App\Model', $class)吗? (我知道您说过您尝试过使用完整的命名空间 - 但您是否尝试过短版本?)

标签: php phpunit laravel-5


【解决方案1】:

模拟 Eloquent 模型的最简单方法是使用 partials:

$mock = m::mock('MyModelClass')->makePartial();

但是,由于您使用的是静态方法 (all()),因此对您的帮助不大。 PHP 不那么严格的特性允许您以非静态方式调用静态方法 ($user->all()),但您应该避免使用它。相反,您应该采取严厉的方式:

$users = $this->user->newQuery()->get();

这可以被嘲笑:

$mockUser->shouldReceive('newQuery->get')->andReturn([/*...*/]);

如果您想更进一步,请将get() 调用移动到注入控制器的单独存储库类中,这将更容易模拟。您可以在网上找到大量关于存储库模式的文章。

【讨论】:

    猜你喜欢
    • 2016-08-17
    • 2015-08-08
    • 2017-09-13
    • 2017-09-02
    • 2014-11-05
    • 2021-12-23
    • 2016-09-24
    • 2015-12-09
    • 2019-06-02
    相关资源
    最近更新 更多