-
-
Notifications
You must be signed in to change notification settings - Fork 158
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
Mocha::Configuration.prevent(:stubbing_non_existent_method) should check Method#arity / Method#parameters #149
Comments
I'm not sure what I was getting at when I said it should check method visibility. Assuming #150 is implemented, then the stub will always have the same visibility as the stubbed method. And in any case, even now there is no way to specify that the stub visibility is anything other than The |
Note that #150 was implemented some time ago. |
I had imagined this check happening at the point where the method was stubbed, but perhaps a better way would be at the point where the stubbed method is invoked. At that point we could check that the parameters with which the method has been invoked are compatible with the original method signature. I'm not quite sure how this would fit in with what we're already doing with the I did a bit of spiking on this approach - I think we'd need to introduce a hook within the method defined in It's also worth looking at how this is implemented in rspec-mocks, most notably the following:
13 Aug 2022: I've just converted all the links to the |
We might want to consider the rspec-mocks idea of operating in two modes i.e. one ("isolation") mode where the stubbed object is not loaded and the arity checks are not performed, and another where the stubbed object is loaded and the arity checks are performed. However this is a non-trivial amount of work and I'm not sure it's sensible to include it in a prospective v1.0 release. I'm now even wondering whether even the basic change is worth including in v1.0. |
Postponing to post-v1.0. |
Also see |
The changes in the spike branch seem to have been confined to a single commit. The changes in that commit were effectively implemented in this commit some 6 years later! So if we did want to introduce a hook along the lines of my earlier comment, it ought to be possible but the code now lives in mocha/lib/mocha/stubbed_method.rb Lines 57 to 64 in ed9c040
|
Unsurprisingly it looks as if RSpec's functionality has moved on considerably since this comment. In particular, verifying doubles now check the method signature using
😂 |
From the RSpec Instance double docs:
|
I hadn't previously thought about this feature in the context of full mocks (i.e. not partial mocks) where a responder has been specified using |
I'm now convinced that this check should be done at stub invocation time.
I'm not sure there's much to be gained by moving this existing check to stub invocation time, although I guess there might be obscure edge cases where a method you want to stub is only defined at run-time. Also in this comment I noted that RSpec does this method existence check at stub definition time. |
Here are some implementation ideas roughly in order of increasing appeal and how speculative they are:
|
This relates to #149 and #531. All the tests seem to pass, but it would be worth doing a bit more thinking about the change in Mock#check_responder_responds_to where we now set include_all to true for the call to Object#respond_to?. Also it's only really worth doing this if the investigation in #531 means that it's definitely worthwhile. It would probably also be worth doing some spiking on the responder-related solution proposed in #149.
This relates to #149 and #531. All the tests seem to pass, but it would be worth doing a bit more thinking about the change in Mock#check_responder_responds_to where we now set include_all to true for the call to Object#respond_to?. Also it's only really worth doing this if the investigation in #531 means that it's definitely worthwhile. It would probably also be worth doing some spiking on the responder-related solution proposed in #149.
This relates to #149 and #531. All the tests seem to pass, but it would be worth doing a bit more thinking about the change in Mock#check_responder_responds_to where we now set include_all to true for the call to Object#respond_to?. Also it's only really worth doing this if the investigation in #531 means that it's definitely worthwhile. It would probably also be worth doing some spiking on the responder-related solution proposed in #149.
This relates to #149 and #531. All the tests seem to pass, but it would be worth doing a bit more thinking about the change in Mock#check_responder_responds_to where we now set include_all to true for the call to Object#respond_to?. Also it's only really worth doing this if the investigation in #531 means that it's definitely worthwhile. It would probably also be worth doing some spiking on the responder-related solution proposed in #149.
This relates to #149 and #531. All the tests seem to pass, but it would be worth doing a bit more thinking about the change in Mock#check_responder_responds_to where we now set include_all to true for the call to Object#respond_to?. Also it's only really worth doing this if the investigation in #531 means that it's definitely worthwhile. It would probably also be worth doing some spiking on the responder-related solution proposed in #149.
This relates to #149 and #531. All the tests seem to pass, but it would be worth doing a bit more thinking about the change in Mock#check_responder_responds_to where we now set include_all to true for the call to Object#respond_to?. Also it's only really worth doing this if the investigation in #531 means that it's definitely worthwhile. It would probably also be worth doing some spiking on the responder-related solution proposed in #149.
We now automatically set a responder on mock object which are used for partial mocks. Having made the change above, I had to set include_all to true for the call to Object#respond_to? in Mock#check_responder_responds_to in order to fix a load of broken tests. The legacy_behaviour_for_array_flatten condition in Mock#check_responder_responds_to is needed to avoid a regression of #580 in Ruby < v2.3. Hopefully this is a small step towards having Configuration.prevent(:stubbing_non_existent_method) check Method#arity and/or Method#parameters (#149) and rationalising Configuration.stubbing_non_existent_method= & Mock#responds_like (#531).
We now automatically set a responder on mock object which are used for partial mocks. Having made the change above, I had to set include_all to true for the call to Object#respond_to? in Mock#check_responder_responds_to in order to fix a load of broken tests. The legacy_behaviour_for_array_flatten condition in Mock#check_responder_responds_to is needed to avoid a regression of #580 in Ruby < v2.3. Hopefully this is a small step towards having Configuration.prevent(:stubbing_non_existent_method) check Method#arity and/or Method#parameters (#149) and rationalising Configuration.stubbing_non_existent_method= & Mock#responds_like (#531).
We now automatically set a responder on mock object which are used for partial mocks. Having made the change above, I had to set include_all to true for the call to Object#respond_to? in Mock#check_responder_responds_to in order to fix a load of broken tests. The legacy_behaviour_for_array_flatten condition in Mock#check_responder_responds_to is needed to avoid a regression of #580 in Ruby < v2.3. Hopefully this is a small step towards having Configuration.prevent(:stubbing_non_existent_method) check Method#arity and/or Method#parameters (#149) and rationalising Configuration.stubbing_non_existent_method= & Mock#responds_like (#531).
When a method doesn't accept keyword arguments. In this scenario keyword or Hash-type arguments are assigned as a single Hash to the last argument without any warnings and strict keyword matching should not have any effect. This is an exploratory spike on fixing #593. * This has highlighted a significant problem with partial mocks in #532. The method obtained from the responder is the stub method defined by Mocha and not the original. This effectively makes it useless! * I'm not sure the method_accepts_keyword_arguments? belongs on Invocation, but that's the most convenient place for now. It feels as if we need to have a bit of a sort out of where various things live and perhaps introduce some new classes to make things clearer. * We might want to think ahead a bit at what we want to do in #149 to decide the best way to go about this. * I'm not sure it's sensible to re-use the Equals matcher; we could instead parameterize PositionalOrKeywordHash, although the logic in there is already quite complex. Conversely if this is a good approach, it might make more sense to do something similar when creating a hash matcher for a non-last parameter to further simplify the code. * I haven't yet introduced any acceptance tests for this and I suspect there might be some edge cases yet to come out of the woodwork. In particular, I think it's worth exhaustively working through the various references mentioned in this comment [1]. [1]: #593 (comment)
And maybe method visibility?
The text was updated successfully, but these errors were encountered: