How can I mock a class during a functional request that is called from within a controller?
Since the request your test is making spins up a completely new PHP process to deliver the contents of that request, nothing you do in-memory during the execution of the test will be reflected in the new HTTP request process.

Fortunately there are some techniques to create HTTP clients that can be used inside functional tests that span longer than a single request. The technique involves creating a test module, which replaces the HTTP client in the container, for all requests that happen while the module is enabled.

Your test may then:


Switch the module on during setup.
Use the new HTTP client in HTTP requests during the lifetime of the test.
Switch the module off, if you're required to clean-up.


The key parts of a test module like this are:

my_module/tests/modules/my_module_http_client/services.yml

services:
  my_module_http_client.http_client:
    decorates: 'http_client'
    class: 'Drupal\my_module_http_client\MockHttpClient'


my_module/tests/modules/my_module_http_client/src/TestHttpClient

&lt;?php

namespace Drupal\my_module_http_client;

use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Response;

/**
 * Test HTTP client for the air quality test.
 */
class TestHttpClient extends Client {

  /**
   * {@inheritdoc}
   */
  public function get($uri, array $options = []) {
    return new Response(200, ['type' =&gt; 'text/xml'], file_get_contents(__DIR__ . '/some-test-fixture.xml'));
  }

}


Of course in the body of ::get, you can program any logic you like. A common pattern is to use the state API to allow the test to specify a behavior for the client. An example might be something like, setting which response fixture to return.

These kind of functional tests are really valuable to ensure your whole system is working end to end. I would however caveat this with saying, it is also valuable to identify units in your controller which can be tested in isolation. Unit tests can often test a lot more scenarios at a might higher speed than a fully bootstrapped implementation might be able to.