如何在Laravel中模拟DB Facade?

5

我正在编写我的单元测试,按照默认设置它们不应该访问数据库。通常情况下,我总是使用Eloquent来获取结果,但有些更复杂的查询必须使用原始的DB。

我有这个函数:

public function GetPassword($email)
{
    $result = DB::table('vin_user_active')
        ->select(
            "vin_user_active.id",
            "vin_user_active.password",
            DB::raw('COALESCE(
                vin_user_active.pass_update_date <=
                CURRENT_TIMESTAMP -
                INTERVAL vin_org_active.password_expiration_days DAY, 0
        ) AS password_expired')
        )
        ->join('vin_org_active', "vin_user_active.org", "=", "vin_org_active.id")
        ->where("email", "=", $email)
        ->first();

    return $result;
}

现在我正在模拟GetPassword函数,但是: 1. 我认为该函数应该是私有的而不是公共的。 2. 覆盖率只有50%,因为它跳过了整个函数。

我该如何模拟它呢?现在我有这个:

$this->db =Mockery::mock('Illuminate\Database\Query\Builder')->makePartial();

    DB::shouldReceive('table')
        ->once()
        ->with("vin_user_active")
        ->andReturn($this->db);

    DB::shouldReceive('raw')
        ->once()
        ->with(Mockery::any())
        ->andReturn(true);

    DB::shouldReceive('select')
        ->once()
        ->with("vin_user_active.id,
            vin_user_active.password,
            DB::raw('COALESCE(
                vin_user_active.pass_update_date <=
                CURRENT_TIMESTAMP -
                INTERVAL vin_org_active.password_expiration_days DAY, 0
        ) AS password_expired'")
        ->andReturn($this->db);

我真的不知道我在干什么,我从来没有模拟过这么多层的函数调用。

有任何想法吗?


你不应该模拟 Laravel 门面,但在测试中可以访问数据库,需要注意的是使用事务以确保数据库查询不会被持久化。 - Mahmoud Tantawy
更多信息请查看 https://laracasts.com/series/phpunit-testing-in-laravel - Mahmoud Tantawy
2
我尽量避免在单元测试中操作数据库(除了我的集成测试需要使用数据库事务)。 - Daniel Angel
9
如果你有成千上万的测试,你不能等到真正的查询运行,你需要像处理其他副作用(API调用等)一样模拟它们,因此在测试中接触真实的数据库是不好的。 - aeryaguzov
4
一年可以学到很多东西,现在我明白了我的评论有点儿愚蠢。 - Mahmoud Tantawy
显示剩余3条评论
2个回答

11

实际上这很简单

    DB::shouldReceive("raw")
        ->set('query', 'query test')
        ->andReturn(true);

-1
相当晚的回答,但是这里有:

DB::spy()


4
这个答案可以从提供更多信息中受益。 - blues

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接