Skip to content

[HttpClient] Add MockResponse::getRequestMethod() and getRequestUrl() to allow inspecting which request has been sent #36487

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 1, 2020
Merged

Conversation

javespi
Copy link
Contributor

@javespi javespi commented Apr 17, 2020

Q A
Branch? 4.4
Bug fix? no
New feature? yes
Deprecations? no
Tickets -
License MIT
Doc PR -

As same as the MockResponse class has getRequestOptions() when doing a request; I've added:

  • getRequestUrl() - returns the URL used when doing the request
  • getRequestMethod() - returns the HTTP method used when doing the request

With these two getters, we would be able to assert that the method and URL passed to the HttpClient were well generated. I've tried to assert the URL generated in a unit test of a class with a SymfonyHttpClient injected and it wasn't possible. Calling $mock->getInfo('url') returns null.

Example, if we have a class with HttpClientInterface injected like this:

final class SymfonyHttpUserClient
{
    private HttpClientInterface $httpClient;
    private string $baseUri;

    public function __construct(
        HttpClientInterface $httpClient,
        string $baseUri
    ) {
        $this->httpClient = $httpClient;
        $this->baseUri = $baseUri;
    }

    public function getById(string $userId): void
    {
        $this->httpClient->request(
            'GET',
            $this->baseUri . $customerId
        );
    }
}

And if we want to do a unit test of SymfonyHttpUserClient right now we are not able to check if the URL of the request was well-formed passing a MockResponse. Also, we weren't able to assert the HTTP method (maybe this piece is not so critical to assert in the unit test).

class SymfonyHttpUserClientTests extends TestCase
{
    public function testGetById(): void
    {
        $baseUri = 'https://user-api.test/api/v1/users/';
        $mockResponse = new MockResponse();
        $symfonyHttpUserClient = new SymfonyHttpUserClient(
            new MockHttpClient(
                [$mockResponse],
                $baseUri
            ),
            $baseUri
        );    

        // test get by id:
        $symfonyHttpUserClient->getById('some-user-id');

        // cannot be asserted right now:
        $this->assertSame($mockResponse->getInfo('url'), $baseUri . 'some-user-id'); // fail
        $this->assertSame($mockResponse->getInfo('http_method'), 'GET'); // fail

        // it could be with the new getters:
        $this->assertSame($mockResponse->getRequestUrl(), $baseUri . 'some-user-id');
        $this->assertSame($mockResponse->getRequestMethod(), 'GET');
    }
}

This only happens if the class has injected the HttpClient and if it is used inside void methods with no being able to return the response. If the class returns the response, url and http_method are available with $response->getInfo() call. But this response object is a new one, is not the mock passed by argument when you instance the MockHttpClient.

Var dumps of getInfo array:

$response->getInfo() from MockClient:

..array(10) {
  ["start_time"]=>
  float(1587109014.7985)
  ["user_data"]=>
  NULL
  ["http_code"]=>
  int(200)
  ["response_headers"]=>
  array(0) {
  }
  ["error"]=>
  NULL
  ["canceled"]=>
  bool(false)
  ["redirect_count"]=>
  int(0)
  ["redirect_url"]=>
  NULL
  ["http_method"]=>
  string(3) "GET"
  ["url"]=>
  string(47) "https://user-api.test/api/v1/users/some-user-id"
}

$mock->getInfo()

array(4) {
  ["http_code"]=>
  int(200)
  ["response_headers"]=>
  array(0) {
  }
  ["error"]=>
  NULL
  ["canceled"]=>
  bool(false)
}

This is a minor change, I opened the PR with 4.4 as base branch; but not sure if it should be opened with 5.0 as base branch or even master taking account is a feature (add two new getters in MockResponse class). Let me know if I didn't follow right the instructions (first PR on Symfony project 😃)

Thanks!

@nicolas-grekas
Copy link
Member

Would it make sense to do $mock->info = &$response->info; instead? That would allow checking any option from the response when having the mock at hand, via getInfo(). Can you give it a try?

@nicolas-grekas nicolas-grekas added this to the next milestone Apr 18, 2020
@javespi
Copy link
Contributor Author

javespi commented Jun 8, 2020

Hi @nicolas-grekas, is there anything I can do to move forward this PR? Thanks! 😃

… to allow inspecting which request has been sent
@nicolas-grekas nicolas-grekas changed the title [HttpClient][MockResponse] Add HTTP method and URL of the request [HttpClient] Add MockResponse::getRequestMethod() and getRequestUrl() to allow inspecting which request has been sent Jun 30, 2020
@nicolas-grekas nicolas-grekas changed the base branch from 4.4 to master June 30, 2020 16:39
Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I just rebased the PR to target master)

@fabpot
Copy link
Member

fabpot commented Jul 1, 2020

Thank you @javespi.

@fabpot fabpot merged commit d8082fa into symfony:master Jul 1, 2020
@javespi javespi deleted the addUrlHttpMethodInMockResponse branch July 1, 2020 13:19
@javespi
Copy link
Contributor Author

javespi commented Jul 1, 2020

Thanks @fabpot @nicolas-grekas for all the effort and support!!

@nicolas-grekas nicolas-grekas modified the milestones: next, 5.2 Oct 5, 2020
@fabpot fabpot mentioned this pull request Oct 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants