shoulda-matchers
shoulda-matchers copied to clipboard
delegate_method doesn't allow me to test #to another class
I have this code that works (I'm not using STI for specific reason, instead I'm simulating MTI):
class AbstractMessage
def self.some_method
#fdfdf
end
end
class Message
class << self
delegate :some_method, to: AbstractMessage
end
end
# Message.some_method will actually call AbstractMessage.some_method
This piece of code works in Ruby, and it actually delegates some_method to the AbstractMessage, however shoulda is not considering this special case.
Thanks for the report, I will take a closer look at this.
I'd like to suggest documenting this as unsupported in the matcher documentation. It should just set out that you need to be delegating to another method on the subject. Then the user can decide whether to hide their class behind an additional method, or not use the matcher.
It'd be nice if it worked, but it looks like that could be difficult because the macro is written assuming delegation to another method on the subject. And this has been open for a while.
@mcmire What can be done to resolve this issue?
@KapilSachdev We would need to update the delegate_method matcher so that instead of merely handling the case in which the argument passed to to is a reference to another method on the same class (in the form of a symbol), we also account for when that argument is another class/module altogether. I don't foresee any real difficulty in doing this, it's just been sitting on the back burner.
Thanks for the feedback. I'm not familiar with the source code, but will try to resolve it.
It's also related to #889 which is the case that you can't delegate to an instance variable either while the actual method does support this. So if any work is done on this issue it might be an idea to also take that case into account.
Is there a way to test the delegate_missing_to method, or would that be out of scope for the gem?
@kushagra-03 Sorry can you elaborate?
Sure, sorry for being cryptic.
Rails added the method #delegate_missing_to, which can be quite handy for blindly forwarding methods.
Would be great to have a shoulda-matcher to spec it.
class Account
has_one :accountable
delegate_missing_to :accountable
...
RSpec.describe Account do
it { is_expected.to delegate_method(any).to(:accountable) }
# OR
it { is_expected.to delegate_missing_method.to(:accountable) }
end
Hope that clears it up @mcmire.