Integration tests mocking facades vs injecting mocks
<p>We have some legacy laravel projects which use facades in the classes. </p>

<pre><code>use Cache;

LegacyClass
{
    public function cacheFunctionOne()
    {
         $result = Cache::someFunction('parameter');

         // logic to manipulate result

         return $result;
    }

    public function cacheFunctionTwo()
    {
         $result = Cache::someFunction('parameter');

         // different logic to manipulate result

         return $result;
    }
}
</code></pre>

<p>Our more recent projects use dependency injection of the underlying laravel classes that the facades represent as has been <a href="http://taylorotwell.com/response-dont-use-facades/">hinted at by Taylor Otwell himself</a>. (We use constructor injection for each class, but to keep the example short, here I use method injection and use a single class.)</p>

<pre><code>use Illuminate\Cache\Repository as Cache;

ModernClass
{
    public function cacheFunctionOne(Cache $cache)
    {
         $result = $cache-&gt;someFunction('parameter');

         // logic to manipulate result

         return $result;
    }

    public function cacheFunctionTwo(Cache $cache)
    {
         $result = $cache-&gt;someFunction('parameter');

         // different logic to manipulate result

         return $result;
    }
}
</code></pre>

<p>I know facades <a href="https://laravel.com/docs/5.1/testing#mocking-facades">can be mocked</a></p>

<pre><code>public function testExample()
{
    Cache::shouldReceive('get')
                -&gt;once()
                -&gt;with('key')
                -&gt;andReturn('value');

    $this-&gt;visit('/users')-&gt;see('value');
}
</code></pre>

<p>Which works nicely for <em>unit tests</em>. The problem I am trying to understand is if these facades are mocked 'globally'.</p>

<p>For example, lets imagine I am writing an integration test (testing a few interconnected classes while mocking services - not an end to end test using live services) which at some point, executes two separate classes <strong>which contain the same facade that calls the same method with the same parameters</strong>. </p>

<p>In between these classes being called, is some complex functionality that changes what data is returned by that facades method using the same parameter.*</p>

<pre><code>$modernClass-&gt;cacheFunctionOne($cache); // easily mocked

// logic that changes data returned by laravel Cache object function 'someFunction'

$modernClass-&gt;cacheFunctionTwo($cache); // easily mocked with a different mock
</code></pre>

<p>Our modern classes are easy to test because the underlying class that the facade represents is injected into each class (in this example, each method). This means I can create two separate mocks and inject them into each class (method) to mock the different results.</p>

<pre><code>$legacyClass-&gt;cacheFunctionOne();

// logic that changes data returned by laravel Cache object function 'someFunction'

$legacyClass-&gt;cacheFunctionTwo();
</code></pre>

<p>In the legacy systems though, it would <em>seem</em> that the mocked facade is 'global' so that when the facade is run in each class, <strong>the exact same value is returned</strong>.</p>

<p>Am I correct in thinking this?</p>

<p>*<em>I understand this example may seem completely redundant from a code architecture and testing point of view, but I am stripping out all real functionality to try and give some sort of 'simple' example of what I am asking.</em></p>