Mock a service while running a BrowserTest?
I could not quite get my mocked service to be used from the container as per the docs, so I resulted to doing this.

I don't really need a BrowserTest per se, as I just want to ensure the Response object contains what it should. I create a client mock and instantiate the controller object myself:

&lt;?php

namespace Drupal\Tests\mymodule\Kernel;

use Drupal\KernelTests\KernelTestBase;
use Drupal\mymodule\Controller\AuthorizeController;
use Drupal\node\Entity\Node;
use Drupal\file\Entity\File;
use Drupal\Core\File\FileSystem;

/**
 * Tests the AuthorizeController controller.
 *
 * @group mymodule
 */
class AuthorizeControllerTest extends KernelTestBase {

  /**
   * @var array
   */
  public static $modules = ['system', 'node', 'field', 'mymodule', 'file', 'mymodule_authtest', 'user', 'text'];

  /**
   * {@inheritdoc}
   */
  public function setUp() {
    parent::setUp();

    $this-&gt;installConfig(['node', 'user', 'mymodule_authtest', 'file']);
    $this-&gt;installSchema('file', ['file_usage']);
    $this-&gt;installEntitySchema('user');
    $this-&gt;installEntitySchema('node');
    $this-&gt;installEntitySchema('file');

    $module_path = drupal_get_path('module', 'mymodule_authtest');

    $uri = $this-&gt;container-&gt;get('file_system')-&gt;copy("$module_path/fixtures/pdf/foo.pdf", 'public://foo.pdf', FileSystem::EXISTS_REPLACE);

    $file = File::Create([
      'uri' =&gt; $uri,
    ]);
    $file-&gt;save();

    $node = Node::create(array(
      'title' =&gt; t('Test Paper'),
      'type' =&gt; 'working_paper',
      'language' =&gt; 'en',
      'field_id' =&gt; 'w12345',
      'field_paper_working_paper' =&gt; $file-&gt;id(),
    ));
    $node-&gt;save();
  }

  /**
   * Test different scenarios and responses from our controller.
   */
  public function testControllerResponse() {
    $node = $this-&gt;container-&gt;get('entity_type.manager')-&gt;getStorage('node')-&gt;load(1);

    $client = $this-&gt;getMockClient(1, 3, 3);
    $controller = $this-&gt;getAuthorizeController($client);
    $response = $controller-&gt;content($node);
    $this-&gt;assertContains('You’ve used 3 of your 3 allowed downloads for the year.', $response-&gt;getContent());
    $this-&gt;assertContains('Download Paper Anyway', $response-&gt;getContent());

    $client = $this-&gt;getMockClient(1, 3, 1);
    $controller = $this-&gt;getAuthorizeController($client);
    $response = $controller-&gt;content($node);
    $this-&gt;assertContains('You’ve used 1 of your 3 allowed downloads for the year.', $response-&gt;getContent());
    $this-&gt;assertContains('Download Paper Anyway', $response-&gt;getContent());

    $client = $this-&gt;getMockClient(1, 2, 1);
    $controller = $this-&gt;getAuthorizeController($client);
    $response = $controller-&gt;content($node);
    $this-&gt;assertContains('You’ve used 1 of your 2 allowed downloads for the year.', $response-&gt;getContent());

    $client = $this-&gt;getMockClient(0, 3, 3);
    $controller = $this-&gt;getAuthorizeController($client);
    $response = $controller-&gt;content($node);
    $this-&gt;assertNotContains('Download Paper Anyway', $response-&gt;getContent());
    $this-&gt;assertContains('&lt;a href="http://example.org?id=w12345" class="btn btn--primary btn--black"&gt;Purchase Paper for $5&lt;/a&gt;', $response-&gt;getContent());
    $this-&gt;assertContains('&lt;a href="http://example.org?referer=http%3A//localhost/node/1" class="btn btn--primary btn--black"&gt;Have Access? Login to Account&lt;/a&gt;', $response-&gt;getContent());
  }

  /**
   * Return a mocked client. Allow changing of some values to influence the
   * controllers response object.
   */
  protected function getMockClient(int $allow = 1, int $claims_max = 3, int $claims_used = 1) {
    $client = $this-&gt;getMockBuilder('\Drupal\mymodule\Client\AuthorizeClient')
      -&gt;disableOriginalConstructor()
      -&gt;getMock();
    $client-&gt;expects($this-&gt;any())
      -&gt;method('request')
      -&gt;with('w12345', FALSE)
      -&gt;willReturn(
        [
          'allow' =&gt; $allow,
          'claims_max' =&gt; $claims_max,
          'claims_used' =&gt; $claims_used,
          'failed_reason' =&gt; NULL,
          'succeeded_reason' =&gt; NULL,
          'subscriber_id' =&gt; 12345,
          'subscriber_logo_url' =&gt; NULL,
          'subscriber_name' =&gt; "Test",
          'subscriber_type' =&gt; "SUBS",
        ]
      );

    return $client;
  }

  /**
   * Return a controller with a mocked client.
   */
  protected function getAuthorizeController($client) {
    return new AuthorizeController($client, $this-&gt;container-&gt;get('renderer'), $this-&gt;container-&gt;get('entity_type.manager'), $this-&gt;container-&gt;get('request_stack'), $this-&gt;container-&gt;get('logger.factory'));
  }

}


This seems like a valid approach and the cases are working, and executes much faster than browser tests. The mymodule_authtest contains a content type with a couple of field configuration files and example PDF file to use in this test.