I'm trying to stub any instance of some class. I need to stub the fetch
method, which fills the self with some data.
How can I get access to self
variable, modify it and return on fetch
method?
MyObject.any_instance.stub(:fetch) { self }
doesn't return a MyObject
instance.
Maybe, mocks is more useful in this situation. Unfortunately, I haven't understood they yet.
Use allow_any_instance_of(Class).to receive when you want to configure how. instances of the given class respond to a message without setting an. expectation that the message will be received.
Mocking with RSpec is done with the rspec-mocks gem. If you have rspec as a dependency in your Gemfile , you already have rspec-mocks available.
In RSpec, a stub is often called a Method Stub, it's a special type of method that “stands in” for an existing method, or for a method that doesn't even exist yet.
RSpec features doubles that can be used as 'stand-ins' to mock an object that's being used by another object. Doubles are useful when testing the behaviour and interaction between objects when we don't want to call the real objects - something that can take time and often has dependencies we're not concerned with.
There's an open rspec-mocks issue to address this. I hope to get around to addressing it at some point, but it's not simple to add this in a way that doesn't break existing spec suites that use any_instance
with a block implementation, because we would start yielding an additional argument (e.g. the object instance).
Overall, any_instance
can come in handy in some situations, but it's a bit of a smell, and you'll generally have fewer issues if you can find a way to mock or stub individual instances.
Here's a work around that I have not tested but should work:
orig_new = MyObject.method(:new)
MyObject.stub(:new) do |*args, &block|
orig_new.call(*args, &block).tap do |instance|
instance.stub(:fetch) { instance }
end
end
Essentially, we're simulating any_instance
here by hooking into MyObject.new
so that we can stub fetch
on each new instance that is instantiated.
All that said, it's important to "listen to your tests", and, when something is hard to test, consider what that says about your design, rather than immediately using power tools like any_instance
. Your original question doesn't give enough context for me to speculate anything about your design, but it's definitely where I would start when faced with a need to do this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With