Symfony HttpClient and sequential requests assertions
Symfony/HttpClient is a powerful component to perform HTTP(s) requests. It already embeds a MockHttpClient and MockResponse to ease testing. When a method performs only one request, it’s very convenient to use, but when the class performs many request and you want to make assertions on the requests it becomes a bit more complex.
Let’s consider a class that performs HTTP requests:
class MyClass
{
public function __construct(
private HttpClientInterface $httpClient,
) {
}
public function sendRequests(): void
{
// In real life, these requests would have been created programmatically.
// Otherwise, it's totally useless to test them!
$this->httpClient->request('GET', 'https://httpbin.org/status/200', ['headers' => ['my-header' => 'foo']]);
$this->httpClient->request('PUT', 'https://httpbin.org/status/201', ['headers' => ['my-header' => 'bar']]);
}
}
Now, we want to test all requests.
If you look at the API you can see you can pass different shapes of data.
Here, we are going to pass a Generator of function. These functions are able to perform assertion on the request. Then they will return a Response.
final class MyClassTest extends TestCase
{
public function test()
{
$httpClient = new MockHttpClient((function (): Generator {
$expectedRequests = [
['GET', 'https://httpbin.org/status/200', 'my-header: foo'],
['PUT', 'https://httpbin.org/status/201', 'my-header: bar'],
];
foreach ($expectedRequests as [$expectedMethod, $expectedUrl, $expectedHeader]) {
yield function (string $method, string $url, array $options) use ($expectedMethod, $expectedUrl, $expectedHeader): ResponseInterface {
$this->assertSame($expectedMethod, $method);
$this->assertSame($expectedUrl, $url);
$this->assertSame($expectedHeader, $options['normalized_headers']['my-header'][0]);
return new MockResponse();
};
}
})());
$myClass = new MyClass($httpClient);
// In real life, you usually pass some parameters to construct all requests.
$myClass->sendRequests();
}
}
The first step is to create a MockHttpClient
. We give it a generator (did you notice the callback is executed right away?).
The generator is responsible for generating a callback that must return a response. One callback per request.
The callback allows us to make some assertion on the method
, the url
, and the options
.
The second and last step is to instantiate MyClass
with the mock HTTP client and execute the method we want to test.
That’s all! ✨
We hope you enjoy this post and see you soon for a new copy/paste snippet!
Commentaires et discussions
Nos formations sur ce sujet
Notre expertise est aussi disponible sous forme de formations professionnelles !
Symfony avancée
Découvrez les fonctionnalités et concepts avancés de Symfony
Ces clients ont profité de notre expertise
Pour La Plateforme du Bâtiment, le début d’année 2014 est le moment de mettre à jour le socle technique du site. JoliCode est donc intervenu aux côtés des équipes internes pour réaliser une migration de Symfony2 de la version 2.0 à la 2.3. Au programme : beaucoup de tests unitaires et fonctionnels, l’installation et l’utilisation de Composer, et une…
La refonte de la plateforme odealarose.com par JoliCode a représenté une transformation complète de tous les aspects de l’application. En charge de l’aspect technique, nous avons collaboré avec Digital Ping Pong (société cofondée par JoliCode), qui a eu en charge à la conception en revisitant entièrement le parcours client et l’esthétique de la plateforme…
Nous avons entrepris une refonte complète du site, initialement développé sur Drupal, dans le but de le consolider et de jeter les bases d’un avenir solide en adoptant Symfony. La plateforme est hautement sophistiquée et propose une pléthore de fonctionnalités, telles que la gestion des abonnements avec Stripe et Paypal, une API pour l’application…