Skip to content
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

Guide "How to mock clients in tests" #177

Open
gregurco opened this issue Jan 4, 2018 · 9 comments
Open

Guide "How to mock clients in tests" #177

gregurco opened this issue Jan 4, 2018 · 9 comments

Comments

@gregurco
Copy link
Member

@gregurco gregurco commented Jan 4, 2018

Write a guide how to mock clients in functional tests.

@Neirda24
Copy link
Contributor

@Neirda24 Neirda24 commented Jan 15, 2018

@gregurco : Here is how I did it: https://gist.github.com/Neirda24/d662dda169518dc75a5beb924c4182c2 tell me what you think

@rrajkomar
Copy link
Contributor

@rrajkomar rrajkomar commented Sep 28, 2018

Any updates on this topic. This is definitely a prerquisite for this bundle to be considered usable in a production system.

@gregurco
Copy link
Member Author

@gregurco gregurco commented Sep 29, 2018

I plan to write it as soon as will finish with guide for plugins. It takes some time.

@bropp
Copy link

@bropp bropp commented Aug 13, 2019

Any thoughts about how to properly provide mock clients in functional tests?

I've been able to configure the bundle to use the MockHandler as described, but don't know how to properly provide the mocked responses in my tests -- the MockHandler queue is always empty.

@ggagosh
Copy link

@ggagosh ggagosh commented Aug 14, 2019

Any news about it?

As we use this as our one of the main bundle need some documentation (examples is great too) about how to mock it the right way.

@gregurco
Copy link
Member Author

@gregurco gregurco commented Aug 16, 2019

@bropp @ggagosh there are a lot of methods how to mock client. Each method is better in special cases. Could you please provide more details on your requirements from your projects and I will try to provide more information. Probably based on these answers we will be able to create documentation page.

@matheusfaustino
Copy link

@matheusfaustino matheusfaustino commented Nov 25, 2019

Hi, first of all, thank you for your lib. I'd like to know if there is a example of how to do the mock. I replaced the handler, it's the MockHandler, but I can't add any request to the queue in the tests. I tried the setHandler method from Guzzle Client and I tried to use reflection class to get the Mock class and append things, but without success.

Could somebody help me with this, please? Thnx in advance

@matheusfaustino
Copy link

@matheusfaustino matheusfaustino commented Nov 25, 2019

Well, I think I found a way through. One thing that I didn't mention before it was that I'm using api-platform and because I'm using api-platform, I'm using its ApiTestCase to write the functional tests, and the problem was that my modifications weren't being applied in the container. But, if I disable the kernel reboot (static::createClient()->disableReboot()), it keeps the modification through all the request at that particular test.

So, I used the code from the tests that @rrajkomar wrote for #221 and disabling the reboot:

static::createClient()->disableReboot();

$cli = static::createClient()->getContainer()->get('eight_points_guzzle.client.<client_name>');
$handlerStack = $cli->getConfig('handler');
$handlerStackRefl = new \ReflectionClass($handlerStack);
$handler = $handlerStackRefl->getProperty('handler');
$handler->setAccessible(true);
$mock = $handler->getValue($handlerStack);

After that, you can append any request into the MockHandler, like:

$mock->append(new Response(200, [], ''));

Api plataform uses SF4, so I just set the MockHandler in the services_test.yaml:

# config/services_test.yaml
eight_points_guzzle:
    clients:
        <client_name>:
            handler: 'GuzzleHttp\Handler\MockHandler'

All that set, you're good to go. I hope it helps ^^

@rrajkomar
Copy link
Contributor

@rrajkomar rrajkomar commented Mar 30, 2021

Coming back to this topic after a while, and a lot more use case experience, I'm no longer convinced the MockHandler was been the best way to implement the mocking mechanism.
Now using a lot of Behat tests, I'm faced with an issue that could not be solved by any of the proposed solution (I even tried an adapted version of @matheusfaustino 's solution, sadly it didn't work as expected)

When using Behat testing, the MockHandler that you fill up with MockResponses is not taken into account once the actual code is called.
This is where disabling the client reboot might have solved some use cases when using the symfony driver (or so I hoped) but even then, when switching to any other driver the solution would no longer be working.

All this leads me to believe going towards a middleware based mocking mechanism might be the best way to handle this problem (although I'm definitely not a fan of a record / replay system, this is so far the most usable I found)

Also it might be the opportunity to revisit the discussion we had way back about setting up a base interface for middlewares (#232):
With autowiring now being a best practice, we could use the interface to get an easily extendable system for middlewares.
(The same kind of system could also be used for plugins, currently having to go change the Kernel class is rather cumbersome)

@gregurco WDYT ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
7 participants