Laravel单元测试模拟eloquent的查询范围方法

时间:2015-01-07 14:45:18

标签: php unit-testing laravel mocking eloquent

我想模拟模型的范围方法,有可能吗?

以下是该方案:

订单型号:

public function scopeForUser($query) // query scope method which should be mocked
{

    return $query->where('user_id', Auth::id());
}

用户模型:

public function getOrders()
{

    $orders = $this->orders(); // Returns Eloquent object(HasMany) 

    $orders->forUser(); // I would like to mock forUser() method

    return $orders->get();
}

测试用例:

public function testGetUsersOrders()
{
    $userOrders = Order::where('user_id', 1);

    // Mock Order's forUser method
    $this->mock =  Mockery::mock('Eloquent', 'Order'); // ?? I can't mock HasMany object, can I?
    $this->app->instance('Order', $this->mock);

    $this->mock->shouldReceive('forUser')->once()->andReturn($userOrders->get());

    $result = $this->user->getOrders();
    $this->assertEquals($userOrders->get(), $result);

}

这是一个简化的例子。

1 个答案:

答案 0 :(得分:0)

建议可能为时已晚,但仅供将来参考:

$hasMany = Mockery::mock->shouldReceive('getResults')
                        ->andReturn($userOrders->get())
                        ->mock();
$this->mock->shouldReceive('forUser')->once()->andReturn($hasMany);

但是你的代码对我来说并没有多大意义。

在你的例子中:

public function getOrders()
{

    $orders = $this->orders(); // Returns Eloquent object(HasMany) 

    $orders->forUser(); // if the above code returns HasMany, Are you trying
                        // to call 'hasMany->forUser()' ?
                        // And even after it is mocked properly and returned
                        // you the '$userOrders->get()'.  It won't do anything
                        // because the result is not kept anywhere and it is 
                        // not used any where neither.

    return $orders->get();  // And then you called 'return $orders->get()'
                            // which has nothing to do with your
                            // '$orders->forUser();'.  It will execute the
                            // $orders you got from the very first line.


}