title: How to write a PHPUnit test for Laravel Artisan command that calls an external API without calling that API physically?
body: <blockquote>
    <p>A brief introduction to give you an idea of what I want to achieve…</p>
  </blockquote>
  
  <p>I have a Laravel 5.6 artisan command that calls an external API with a simple GET request to get some data. I want to test this <strong>without actually calling any API</strong> physically. (I want to be offline and still have test test green).</p>
  
  <p>Now a brief explanation of how the logic is arranged.</p>
  
  <p>1) <strong>This artisan command (<code>php artisan export:data</code>) has its own constructor</strong> (<code>__construct</code>) where I inject bunch of stuff. One of the things I inject is the <code>ExportApiService</code> class. Easy.</p>
  
  <pre><code>public function __construct(
      ExportApiService $exportApiService,
  ) {
      parent::__construct();
  
      $this-&gt;exportApiService = $exportApiService;
  }
  </code></pre>
  
  <p>2) Now <code>ExportApiService</code> extends <code>abstract class AbstractApiService</code>. Inside this abstract class I made a constructor where I simply inject <code>GuzzleHttp\Client</code> in a <code>$client</code> property so that in <code>ExportApiService</code> I can call API by using <code>$this-&gt;client</code>. Easy.</p>
  
  <p>3) So my <code>ExportApiService</code> has a method called <code>exportData</code>. Trivial. Works.</p>
  
  <pre><code>public function exportData(array $args = []): Collection
  {
     $response = $this-&gt;client-&gt;request('GET', 'https://blahblah.blah');
  
     return collect(json_decode($response-&gt;getBody()-&gt;getContents(), true));
  }
  </code></pre>
  
  <p>4) <strong>So finally</strong> in my artisan command (that I introduced in point no. 1) I call:</p>
  
  <pre><code>public function handle()
  {
      $exportedData = $this-&gt;exportApiService-&gt;exportData($this-&gt;args);
  
      $this-&gt;info('Exported ' . count($exportedData) . ' records');
  }
  </code></pre>
  
  <p>I want to test if the output matches my expectations <strong>without calling that external API at all</strong>. I want to mock it somehow…</p>
  
  <pre><code>public function testExportSuccessful()
  {
      $this-&gt;console-&gt;call('export:data', [$some_arguments]);
  
      $output = $this-&gt;console-&gt;output();
  
      $this-&gt;assertContains('Exported 123 records', $output); // this does not work :(
  }
  </code></pre>
  
  <p>Now my exact question - <strong>how can I force Laravel / PHPUnit to return a fixed value every time the artisan command will call <code>exportData()</code>?</strong></p>
  
  <blockquote>
    <p>What did you try?</p>
  </blockquote>
  
  <p>I tried creating a <code>setUp()</code> method with the following code:</p>
  
  <pre><code>public function setUp()
  {
      parent::setUp();
  
      $mock = $this-&gt;createMock(ExportApiService::class);
  
      $mock-&gt;method('exportData')-&gt;willReturn(123); // give me a dummy integer each time exportData is being called so that I can use is in the assert at the end
  }
  </code></pre>
  
  <p>But this does not work at all however it makes sense to me.</p>
  
  <p>Thank you for any help.</p>