title: Integration tests mocking facades vs injecting mocks
body: <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>