Доступ к свойствам из классов внутри черт - PullRequest
0 голосов
/ 14 марта 2020

Я пытаюсь написать модульный тест для метода startedAt(), используя mocks, однако проблема, с которой я сталкиваюсь, заключается в том, что я не думаю, что могу получить доступ к экземпляру компоновщика из этого метода startedAt().

Чтобы протестировать метод startedAt(), я создал класс прибора с именем ExampleFilters и расширил его родительский класс на Filters. Внутри класса ExampleFilters я импортирую черту FiltersByStartDate.

У кого-нибудь есть предложения о том, как я могу получить доступ к свойству builder из черты FiltersByStartDate?

Любой идеи по этому поводу?

<?php

namespace App\Filters\Concerns;

trait FiltersByStartDate
{
    /**
     * Filter a query to include models of a specific date started.
     *
     * @param  array  $startedAt
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function startedAt($startedAt)
    {
        if (isset($startedAt[1])) {
            $this->builder->whereHas('currentEmployment', function ($query) use ($startedAt) {
                $query->whereBetween('started_at', [
                    $startedAt[0],
                    $startedAt[1]
                ]);
            });
        } else {
            $this->builder->whereHas('currentEmployment', function ($query) use ($startedAt) {
                $query->whereDate('started_at', $startedAt[0]);
            });
        }

        return $this->builder;
    }
}
<?php

namespace Tests\Fixtures;

use App\Filters\Concerns\FiltersByStartDate;
use App\Filters\Filters;

class ExampleFilters extends Filters
{
    use FiltersByStartDate;
}
<?php

namespace App\Filters;

use Illuminate\Http\Request;

abstract class Filters
{
    /**
     * @var \Illuminate\Http\Request
     */
    protected $request;

    /**
     * The Eloquent builder.
     *
     * @var \Illuminate\Database\Eloquent\Builder
     */
    protected $builder;

    /**
     * Registered filters to operate upon
     *
     * @var array
     */
    protected $filters = [];

    /**
     * Create a new class instance.
     *
     * @param \Illuminate\Http\Request $request
     */
    public function __construct(Request $request)
    {
        $this->request = $request;
    }

    /**
     * Apply the filters.
     *
     * @param  \Illuminate\Database\Eloquent\Builder $builder
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function apply($builder)
    {
        $this->builder = $builder;

        foreach ($this->getFilters() as $filter => $value) {
            if (method_exists($this, $filter)) {
                $this->$filter($value);
            }
        }

        return $this->builder;
    }

    /**
     * Fetch all relevant filters from the request.
     *
     * @return array
     */
    public function getFilters()
    {
        return array_filter($this->request->only($this->filters));
    }
}
<?php

namespace Tests\Unit\Filters\Concerns;

use Illuminate\Database\Query\Builder;
use Tests\Fixtures\ExampleFilters;
use Tests\TestCase;

/*
 * @group filters
 */
class FiltersByStartDateTest extends TestCase
{
    /* @var Tests\Fixtures\ExampleFilters */
    protected $subject;

    public function setUp(): void
    {
        $this->subject = app(ExampleFilters::class);
    }

    /** @test */
    public function models_can_be_filtered_by_their_start_date()
    {
        // $this->markTestIncomplete();

        $dateSet = ['2020-01-01 00:00:00'];

        $mock = \Mockery::mock(Builder::class)
            ->shouldReceive('whereHas', \Mockery::any())
            ->shouldReceive('whereDate')
            ->withArgs(['started_at', $dateSet])
            ->once()
            ->andReturn(true)
            ->getMock();

        dd($this->subject->startedAt($dateSet));

        $builderMockFromDate = $this->subject->startedAt($dateSet);

        $this->assertSame($builderMockFromDate, $mock);
    }
}
...