Laravel facade class not found when mocked in a unit test
Asked Answered
S

2

8

I might be missing something here but I have a very simple helper class that creates a directory:

// Helper class

<?php namespace MyApp\Helpers;

    use User;
    use File;

    class FileSystemHelper
    {
        protected $userBin = 'users/uploads';

        public function createUserUploadBin(User $user)
        {
            $path = $this->userBin . '/' . $user->id;

            if ( ! File::isDirectory($path))
            {
                File::makeDirectory($path);
            }
        }
    }

And associated test here:

// Associated test class

<?php 

    use MyApp\Helpers\FileSystemHelper;

    class FileSystemHelperTest extends TestCase {

        protected $fileSystemHelper;

        public function setUp()
        {
            $this->fileSystemHelper = new FileSystemHelper;
        }

        public function testNewUploadBinCreatedWhenNotExists()
        {
            $user = new User; // this would be mocked

            File::shouldReceive('makeDirectory')->once();

            $this->fileSystemHelper->createUserUploadBin($user);
        }
    }

However I get a fatal error when running the test:

PHP Fatal error: Class 'File' not found in /my/app/folder/app/tests/lib/myapp/helpers/FileSystemHelperTest.php

I've looked at the docs for mocking a facade and I can't see where I'm going wrong. Any suggestions?

Thanks

Strangury answered 25/6, 2013 at 9:53 Comment(0)
S
25

I missed this in the docs:

Note: If you define your own setUp method, be sure to call parent::setUp.

Calling that cured the problem. Doh!

Strangury answered 25/6, 2013 at 12:18 Comment(1)
Thanks, I got the error Call to undefined method Illuminate\Support\Facades\Log::channel() without it.Sainthood
H
4

it's because laravel framework is not loaded before using facade OR it because you are not using laravel php unit(TestCase class) here is a sample code to test case that are in app/ //attention to extends from TestCase not ()

/**
 * TEST CASE the application.
 *
 */
class TestCase extends Illuminate\Foundation\Testing\TestCase {

    /**
     * Creates the application.
     *
     * @return \Symfony\Component\HttpKernel\HttpKernelInterface
     */
    public function createApplication()
    {
        $unitTesting = true;

        $testEnvironment = 'testing';

        //this line boot the laravel framework so all facades are in your hand
        return require __DIR__.'/../../bootstrap/start.php';
   }

}

Hazzard answered 28/2, 2015 at 10:39 Comment(2)
Worked for me - thanks! For some reason my code was extending PHPUnit_Framework_TestCase instead of the Illuminate version :/Aracelis
Valid answer with Laravel 5.3 (yes, I know, old).Counterwork

© 2022 - 2024 — McMap. All rights reserved.