AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |
Back to Blog
Phpunit mocks4/5/2023 These helpers primarily provide a convenience layer over Mockery so you do not have to manually make complicated Mockery method calls. Laravel provides helpful methods for mocking events, jobs, and other facades out of the box. This allows you to only test the controller's HTTP response without worrying about the execution of the event listeners since the event listeners can be tested in their own test case. For example, when testing a controller that dispatches an event, you may wish to mock the event listeners so they are not actually executed during the test. If ($method = 'GET' & str_starts_with($url, $this->baseUri.When testing Laravel applications, you may wish to "mock" certain aspects of your application so they are not actually executed during a given test. Private function handleRequests(string $method, string $url): MockResponse This class, therefore, extends MockHttpClient: Let's add the src/Tests/Mock/AbstractApiMock.php file. Perfect! As expected, this class implements the HttpClientInterface. * A test-friendly HttpClient that doesn't make actual HTTP requests.Ĭlass MockHttpClient implements HttpClientInterface, ResetInterface Let's look at its declaration (thank you, Nicolas and other contributors, for the component by the way, □): We don't have to reinvent the wheel the HTTP component already contains such a class: the MockHttpClient. This is what we are going to do in the test environment.īarbara Liskov Creating the HttpInterface mock This means that we respect the Liskov substitution principle, and we can replace the client with any object implementing the HttpClientInterface. The most important is that we inject a HttpClientInterface in our service. I also set a specific user agent, but it's not mandatory. And as you can see, we set several headers to tell that we consume the API with JSON thanks to the Accept and Content-Type keys. It's exactly what we did in our service: private HttpClientInterface $abstractApiClient. They are ready to inject into our services. But how does it work if we have several clients? Well, cherry-on-the-cake, Symfony creates named parameters for each scoped clients. It creates a service for each declared client, so they are ready to be used. When declaring this configuration, the Symfony HTTP component does several interesting things. When using it, we only have to deal with relative URLs of endpoints and forget about the protocol and domain. We use a scoped client this means that the client is bound to a given URL. # Specialized client to consume the AbstractAPI To be able to inject the HTTP client service, it must be declared this is done in the config/packages/framework.yaml file: Let's see how the HTTP client is configured. There is only one function, it prepares the request to send with setting the IP to use, and the secret key to be identified (passing a secret key as a GET parameter isn't really a good practice, in this case, it would be better in a header for example). As we can see, the service implements the HttpClientInterface. Some notes about this service we inject one service and a parameter. Return $this->abstractApiClient->request('GET', '/v1', )->toArray() 'ip_address' => $ip, // if IP is not set, it uses the one of the current request 'api_key' => $this->abstractApiKey, // your secret API key Public function getData(string $ip): array Let's have a look at the service in charge of collecting the data from the external API: The action behind it is classic it's glue code calling the service to get the user's IP and passing it to the Twig template. This test is straightforward it's a "smoke" test we only test if the page works, doesn't return a 500 error and if it shows the user's IP. Self::assertStringContainsString('Your IP is:', $content) $content = (string) $client->getResponse()->getContent() $client->request('GET', '/en/tools/what-is-my-ip') We will use a simple solution avoiding using an external dependency.įirst, let's have a look at an external test: The goal is to use a mock instead of an actual HTTP call in the test environment. That means that can we simulate a real response with fake data that respect the structure of the original data source. But what if we don't want to make network calls to run the test offline? We can use what we call "mocks". We had a particular category, "external", making actual HTTP request on the network. In my previous article, we saw how to organize the tests of a Symfony application. I will assume you have at least a basic knowledge of Symfony and you know how to test an application with PHPUnit (check my last article on the subject). » Published in "A week of Symfony 791" (21-27 February 2022).
0 Comments
Read More
Leave a Reply. |