jrdavidson's avatar

Trying to Test a Mock of a Filters Class

I'm attempting to try and unit test the class below. I don't know if this is the proper way to do it but this is what I"m attempting. The first assertion in each test fails due to these error messages.

Failed asserting that an array contains 'App\Filters\Concerns\FiltersByStatus'. Failed asserting that an array contains 'App\Filters\Concerns\FiltersByStartDate'.

What suggestions does anyone have to correct this error or perhaps better write the test for this?

<?php

namespace App\Filters;

class UserFilters extends Filters
{
    use Concerns\FiltersByStartDate,
        Concerns\FiltersByStatus;

    /**
     * Registered filters to operate upon.
     *
     * @var array
     */
    public $filters = ['status', 'started_at'];
}

<?php

namespace Tests\Unit\Filters;

use App\Filters\Concerns\FiltersByStartDate;
use App\Filters\Concerns\FiltersByStatus;
use App\Filters\UserFilters;
use Tests\TestCase;

class UserFiltersTest extends TestCase
{
    /** @var App\Filters\UserFilters */
    protected $subject;

    /**
     * Setup the test environment.
     *
     * @return void
     */
    protected function setUp(): void
    {
        parent::setUp();

        $this->subject = $this->mock(UserFilters::class);
    }

    /** @test */
    public function user_filters_include_filtering_by_status()
    {
        $this->assertUsesTrait(FiltersByStatus::class, $this->subject);
        $this->assertTrue(in_array('status', get_class($this->subject)->filters));
    }

    /** @test */
    public function user_filters_include_filtering_by_started_at_date()
    {
        $this->assertUsesTrait(FiltersByStartDate::class, $this->subject);
        $this->assertTrue(in_array('started_at', $this->subject->filters));
    }
}
0 likes
4 replies
bobbybouwmann's avatar

Well, the tests fail because they are mock classes. The mock is a complete different class than the UserFilters class you expect.

In your current test, there is also no reason to use a mock. You can just say $this->subject = UserFilters::class and all tests should pass ;)

1 like
jrdavidson's avatar

@bobbybouwmann I can't do that because $this->subject would not ber an object just the returned string representation of thhe class path.

bobbybouwmann's avatar
Level 88

You can change it to this

$this->subject = new UserFilters();

If your UserFilters has a constructor with dependencies that need to be loaded you can use the app helper

$this->subject = app(UserFilters::class);
1 like
jrdavidson's avatar

@bobbybouwmann Is there something that can help me understand using the app helper because of the class taking on the Request class as a dependency?

Please or to participate in this conversation.