Laravel - ложное выражение БД - PullRequest
1 голос
/ 22 февраля 2020

Как бы я посмеялся над предложением where?

->where(DB::raw('NOW()'), '<', DB::raw('(ue.accepted_at + INTERVAL 1 YEAR)'))

Вот как выглядит тест:

$mockQueryBuilder
    ->shouldReceive('select')->twice()->andReturnSelf()
    ->shouldReceive('from')->once()->andReturnSelf()
    ->shouldReceive('join')->twice()->andReturnSelf()
    ->shouldReceive('where')->with('ue.user_id', $user->id)->once()->andReturnSelf()
    ->shouldReceive('where')->with('e.type_id', 1)->once()->andReturnSelf()
    ->shouldReceive('where')->with(function (\Closure $closure) {})->andReturnSelf() // This should be testing the raw expression
    ->shouldReceive('whereNull')->with('e.deleted_at')->once()->andReturnSelf()
    ->shouldReceive('whereNotNull')->with('e.published_at')->once()->andReturnSelf();

1 Ответ

1 голос
/ 25 февраля 2020

При работе с сопоставлением с объектами наилучшим подходом является написание пользовательских сопоставлений из-за принципа равенства на объектах. Например, DB::raw('1') !== DB::raw('1').

A Matcher для работы с db raw будет выглядеть что-то вроде этого.

use Mockery\Matcher\MatcherAbstract;

class DBRawMatcher extends MatcherAbstract
{
    /** @var string */
    private $expression;

    public function __construct(string $expression) {
        $this->expression = $expression;
    }

    public function match(&$actual) {
        // $actual is of type Expression
        return $actual->getValue() === $this->expression;
    }

    public function __toString()
    {
        return 'DBRawMatcher';
    }
}

Просто сохраните исходные данные вашей DB в класс и распакуйте выражение, которое возвращает db raw. Затем сравнивает, что это то же самое.

Теперь вы можете создать свои насмешливые логи c.

->shouldReceive('where')->once()->with(
    new DBRawMatcher('NOW()'),
    '>',
    new DBRawMatcher('(ue.accepted_at + INTERVAL 1 YEAR)')
)->andReturnSelf()
...