Mocking Request in Laravel 5.1 for (actual) Unit Test

You will always run into problems trying to properly unit test controllers. I recommend acceptance testing them with something like Codeception. Using acceptance tests you can ensure your controllers/views are handling any data appropriately.


Unit testing a controller when using Laravel doesn't seem like a great idea. I wouldn't be concerned with the individual methods that are being called on the Request, Response and maybe even the repository classes, given the context of a Controller.

Furthermore, unit testing a controller belonging to a framework because you want to decouple the test sut from its dependencies doesn't make sense, as you can only use that controller in that framework with those given dependencies.

As the request, response and other classes are all fully tested (either via the underlying Symfony class, or by Laravel itself), as a developer I'd concern myself only with testing the code I own.

I'd write an acceptance test.

<?php

use App\User;
use App\Page;
use App\Template;
use App\PageType;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class CategoryControllerTest extends TestCase
{
    use DatabaseTransactions;

    /** @test */
    public function test__it_shows_a_paginated_list_of_categories()
    {
        // Arrange
        $categories = factory(Category::class, 30)->create();

        // Act
        $this->visit('/categories')

        // Assert
            ->see('Total categories: 30')
            // Additional assertions to verify the right categories can be seen may be a useful additional test
            ->seePageIs('/categories')
            ->click('Next')
            ->seePageIs('/categories?page=2')
            ->click('Previous')
            ->seePageIs('/categories?page=1');
    }

}

Because this test uses the DatabaseTransactions trait, it's easy to perform the arrange part of the process, which almost allows you to read this as a pseudo-unit test (but that's a slight stretch of the imagination).

Most importantly, this test verifies that my expectations are met. My test is called test_it_shows_a_paginated_list_of_categories and my version of the test does exactly that. I feel the unit test route only asserts that a bunch of methods are called, but doesn't ever verify that I'm showing a list of the given categories on a page.