Thanks for your answer
Why not?
Because it is absolutey counter intuitive. When I call Container.stub(...)
, my intent is to stub what the container does when someone calls Container[...]
.
Consider the parallel with a method stub : When I stub the method, I do not expect the actual method to run but change what it returns, I want to actually prevent the method to run and instead return another value. If I use this example to its maximum potential, I think I would actually enjoy having a Container.stub(key,&blk)
where blk could the the prepare + start code to create the stubbed value in a very similar way to how stubbing a method works.
Maybe we could have an explicit Container.stub(key, boot_original: true)
for when we actually want the bootable component to boot but I would bet that this is not the usage most people want.
Using Webmock for integration testing, definitely makes sense. The question with integration testing is always “how far goes the scope”, I like to have a scope covers only my own code and does not cover external libraries and standard lib. This is why I use the container to provide me things like Open3
, CSV
, AWS::S3::Resource
, … Typically I do not consider that a developer but know anything about what exactly the s3_client does on the network to use it.
Also it makes my specs more stable, if at some point the gem is updated and uses the new version of the AWS API, my tests won’t have to change. If I used webmock, I would have to change my tests even though nothing in my own code justifies it.
Alternatively, you could mock out the client in your test subject
That’s what I ended up doing. Effectively changing my integration spec in a unit spec.
If I want to have some non-stubbed dependencies, I’ll simply instantiate them manually. This has the big downside of making me not test the integration with the container and auto injection.
Finally, since providers can be optionally switched off, I suppose you could exclude it from the test environment and register the key in your spec config.
I did not know about this but I’m not inclined to do so :
- As you said, I may want to have the real client in some tests
- I hate when my code has environment-related conditions. I have an environment specific “loader” ( spec_helper), that is the piece of code responsible for setting up everything that is test oriented. If I start spreading environment specific condition in my code, I’ll live a maintenance hell and a communication hell with my team.
Thank you again for your answer. I understand that what I wanted is not doable but you provided interesting workaround. I hope my explanations can be useful for anyone working on the gem in the future but as they say “beggars are not choosers”