Symfony 5: how do I mock HttpClientInterface in integration test?

In a Symfony environment services are private, but this is not a problem because you are getting them in your controllers, services, etc through Dependency Injection, meaning that it is Symfony itself that takes care of it.

When trying to test, you may end up, like in your case, setting the mocked class in your container directly.

This will throw the error you see.

To overcome this error, in your services.yaml file located in the config folder, just add the following lines at the bottom:

when@test:
    services:
        _defaults:
            public: true

        test.Symfony\Contracts\HttpClient\HttpClientInterface: '@Symfony\Contracts\HttpClient\HttpClientInterface'

what you are doing here, is telling Symfony that during tests you will have a public Service called test.Symfony\Contracts\HttpClient\HttpClientInterface that it is a copy of the HTTPClientInterface class.

Now, in your test code you can do the following:

$response = new MockResponse(null, ['http_code' => 200]);
$client->getContainer()->('test.Symfony\Contracts\HttpClient\HttpClientInterface', new TraceableHttpClient(new MockHttpClient($response)));