-
Notifications
You must be signed in to change notification settings - Fork 71
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
How to use Guzzle mock handlers with EightPointsGuzzleBundle #195
Comments
Hello @rtfjr86 . Do you expect different responses for the same client in tests or there is always the same response? If the same then there is easy solution. |
@rtfjr86 did you see this repository https://github.com/FriendsOfBehat/ServiceContainerExtension ? Does it help you? |
@gregurco Thank for the quick response. I know that the guzzle mock handler can be have multiple responses in a queue. I expect that each of those responses have a different body. I'd like to do something like:
I am trying to set theses responses in the guzzle mock handler. It seems to work for the first request, but the second is using the curl handler. I will definitely take a look at https://github.com/FriendsOfBehat/ServiceContainerExtension. Thanks. (please forgive my code formatting 😅) |
I'm looking to be able to do something like
on the line below.
|
@rtfjr86 @gregurco
I want log request body for debug. |
@lcp0578 just create listener and listen |
@gregurco thanks |
services.yml
Can you give me more hints about how to implement |
@lcp0578 try next way: namespace ApiBundle\EventListener;
use EightPoints\Bundle\GuzzleBundle\Events\GuzzleEventListenerInterface;
use EightPoints\Bundle\GuzzleBundle\Events\PostTransactionEvent;
class RequestListener implements GuzzleEventListenerInterface
{
public function onPostTransaction(PostTransactionEvent $event)
{
if ($event->getServiceName() === 'api_department') {
// do some logic
}
}
} |
@gregurco thank you very munch! |
Hello, Would it be possible to add an option in the configuration to choose a specific handler to use ? |
As far as I could see, there seems to be three possible ways :
Any feedback on those ideas would be nice to start thinking about its implementation. |
@rrajkomar sorry for the delay. Could you please explain why not to mock the whole client and just the HandlerStack? I guess it's better and then you get the full access on call of methods and so on. |
I could mock the clients... if I knew how to do it :-) |
If you're using SF 4 then just create config file
Also you have another possibility to replace service in container in tests env. Just write next functionality in your
|
I don't like the first solution as it requires me to add some more classes for the mocks (while I won't be needing them) : I'm already using custom classes for the actual clients. The second solution is better but requires me to write several lines of code to replace each client by a mock... I was rather expecting a solution like this (which I thought about yesterday) : somewhat like what was suggested in #195 (comment) That way no need to write multiple lines of code and the configuration remains simple |
@rrajkomar got it and it makes sense. If you will give me example of your "mock of handler stack" then I can help you with adjustments on bundle's side. |
I'll create a fork of the project and make the changes there then link it back here so you can see what I had in mind. @gregurco : Here you can see what I was thinking of more or less. (sorry didn't have time to write the tests but this should give an idea) : rrajkomar@29dee73 I only configured the mockhandler to be integrated, not sure whether the complete choice (using the options entry) should be given, because the handler can be any callable, but I'm not sure how Definition will react if something else than a class name is provided. It may be best to only set a boolean node mock_api_calls: T/F instead of allowing a direct setting of the handler class... |
@gregurco : I've been working on the issue again during the week end. It seems the Definition is created only once and not one per client with is problematic because if you have multiple clients, you cannot define a specific handler for only one client. Any ideas on how to work past this ? |
@rrajkomar yep, you are right. I think there is no restriction to change the definition of handler and you can change that one client will have one separate handler. What do you think? |
Mmm Not sure I understood your reply... 😕 |
For now all clients have one handler and it creates problems if we want to redefine/mock just one handler for specific client. And I guess in this case we have only one solution: to create separate handler for each client. Write me if it's clear now. |
Yes that's, what I started workign on locally but got stuck with the issue that it does not seem to be possible to create multiple definitions with the same "target" class. Or I missed something somewhere. Here's what I wrote on my dev :
then I tried
but neither worked 😞 |
https://github.com/rrajkomar/EightPointsGuzzleBundle/blob/master/src/DependencyInjection/EightPointsGuzzleExtension.php#L78 - I think here we should be returned |
I'll try this evening and get back to you. |
Here you go. |
Actually, I've already took the liberty of updating the README.md file to add the related documentation. |
I'm using Behat for testing. My application uses Guzzle to consume other services. When testing, I'm replacing the client in the container with my client that has a mock handler. It works fine until my test makes a second request, then it seems my client is replaced with the original. Is there a way to ensure that a mocked response is always returned when testing? Thanks.
FeatureContext.php
$this ->getSession() ->getDriver() ->getClient() ->getContainer() ->set( 'eight_points_guzzle.client.products_service', $this->getMockClient($responses) );
test.feature
When I go to "/some/url"
And I reload the page
The first request returns the mocked response. The second makes a cURL request.
The text was updated successfully, but these errors were encountered: