Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

llhilton's avatar

Paginator paths not matching

New to testing, so please point out anything that sounds wrong in what I'm saying, because I may well not know it.

I'd like to test that, when you come to this page, you get a view with a paginated collection of sites, and that it has the right values. My test class is below.

class SiteTest extends TestCase
{
<snip>
    public function __construct()
    {
        $this->baseUrl = 'https://prefix.mysite.com';
    }
<snip>

    /**
     * Test that visiting the index page shows us the first ten sites
     *
     * @return void
     */
    public function testItShowsAPageOfTenSites()
    {
        $dbSites = Site::where('is_active', 1)->orderBy('site_name', 'asc')->paginate(10);
        $res = $this->call('GET', '/administration/site-management');
        $this->assertResponseOk();
        $this->assertViewHas('sites', $dbSites);
    }
}

I get an error, though, that the paths aren't the same: Failed asserting that two objects are equal.

--- Expected
+++ Actual
@@ @@
     'currentPage' => 1
-    'path' => 'http://localhost/'
+    'path' => 'https://prefix.mysite.com/administration/site-management/'
     'query' => Array ()
     'fragment' => null
     'pageName' => 'page'
 )

Note that I overwrite the baseUrl, because otherwise I get a 404 error. (There's some weird stuff going on in the routing that I can't change and so mostly have learned to live with in other aspects.) I tried tweaking the baseUrl in the TestCase class, but it still used localhost. Path is protected, so I can't even just force it to match.

So, is there a way to exclude it from checking the path? I'd even be content with just checking the first elements of the two match.

Further, any thoughts on the approach? I've been watching Jeffrey's videos and reading and re-reading documentation and tutorials and the like, but I still feel deeply at sea in this world of test. Thanks in advance!

0 likes
3 replies
ifpingram's avatar
Level 4

I would not go about testing it this way. Testing data objects against other objects, as testing the bound data is doing is always going to lead to problems.

Firstly, I would use the DatabaseMigrations trait, to test against seed data, as opposed to live data (which it looks like you are currently doing).

Secondly, if you have a piece of identifying data (like a name or ID) which is being displayed in the view, then you can assert against these, as opposed to asserting against the data bound into the view.

llhilton's avatar

Thanks for the insight! Very helpful. :) I've tossed in the migration as well as the transaction trait. For seeding, I'm using a seeder, but the information for it has already changed once, and it may change again before this build is done. (Which is probably at least several months away at the rate it's going.) I'd rather not trust myself to remember to update both the seeder and the test. (Let's be honest--I don't!) :) So I'm currently pulling information out and then testing to see if it shows up as it should. But, as I'm new to testing, I realize maybe I need to change my thinking and ALWAYS be thinking tests too? I'd appreciate any thoughts on that!

Current function looks like this:

public function testItShowsAPageOfTenSites()
    {
        // Get the first 11 active sites
        $activeSites = Site::where('is_active', 1)->orderBy('site_name', 'asc')->limit(11)->get()->lists('site_name')->toArray();

        // Get 1 inactive site
        $inactiveSite = Site::where('is_active', 0)->orderBy('site_name', 'asc')->limit(1)->get()->lists('site_name')->toArray();

        // Check the page to make sure that heading stuff is loading
        $this->visit('/administration/site-management')
            ->see('Sites')
            ->see('Search for a site:')
            ->see('Results per page')
            ->see('Name')
            ->see('Url');

        // Check to make sure the first ten sites show up.
        for ($i = 0; $i > 11; $i++) {
            $this->see($site);
        }

        // Check to make sure the pagination is working by the 11th item not being visible.
        $this->dontSee($activeSites[10]);

        // Check to make sure that inactive sites aren't showing up.
        $this->dontSee($inactiveSite[0]);
    }
ifpingram's avatar

That's definitely looking better in terms of the test logic. Where do you seed the database? Usually I will do it in the test itself, as it is rare that I need the same seeds across all tests in a test class (which I would seed in a setUp function). Remember a test seed is only set in the database for the duration of the test which uses it. Therefore you often seed each test differently, in order to account for the edge-cases of the system functionality.

Regards your schema - it's guaranteed it will change - they always do! :) I would recommend just picking out a field that you think is least likely to change in the schema, like "site_name", "site_url" etc. This way, hopefully any changes to the schema are less likely to involve a need to change the test also. You do not need to test every column in the model. You only need to test what is pertinent to the test. In this case, you are looking to see the inclusion of sites on the page, therefore using the Site Name column will be fine.

But, as I'm new to testing, I realize maybe I need to change my thinking and ALWAYS be thinking tests too? I'd appreciate any thoughts on that!

IMO you should be thinking about your tests 100% of the time. As I use TDD for 90% of the code I write, I really only think in terms of tests nowadays. Often I will "spike" out an implementation idea, to get an idea of where I think the code may go, but then once it works, I will delete it, write some tests and then implement it. Throwing away code may seem counter-intuitive, but in fact it is not; the will be numerous nuances that I miss in the spiked code, which the tests will pick up on, ensuring I have a better quality of code in the real implementation.

Please or to participate in this conversation.