Closed archit closed 11 years ago
The way that RR works is that if you are stubbing (or mocking) a method that doesn't exist, instead of creating a method within that object which calls your block, it actually creates a #method_missing method which calls your block (assuming the missing method is the one you're stubbing/mocking). Before obj.extend(Validator)
, #invalid? on object
doesn't exist, and so when you say stub(@object).invalid? { false }
, RR will create #method_missing. Once the object is extended with Validator, then #invalid? springs into existence, and that essentially ends up overriding #method_missing.
Honestly I'm not sure what the reasoning behind this was so I'd have to look into this for you. But at least at the moment you can try something like this:
class SubjectTest < UnitTest
setup do
@object = Resource.new
@subject = Subject.new
end
should "do_something_else if resource is valid" do
@object.extend(Module.new { def invalid?; end })
stub(@object).invalid? { false }
@subject.foo(@object)
end
end
Here we mix an anonymous module into @object
which defines a dummy #invalid? method. This way, when the stub occurs, it will replace #invalid? rather than defining #method_missing. When @subject.foo is called, Validator will be mixed into @object
which will override our dummy method but not override the stub method (since that is defined directly in @object
's metaclass).
@mcmire ah good to know about how the internals work. Yeah I'm primarily what I'm looking to do is really stub out a whole module, so I'm going with my monkey-patching way. I'll try out your way in the meantime. Thanks!
Okay, cool. I'm closing this issue since it's a question, but let me know if it doesn't work and I'll try to help you further.
I have ruby code similar to this
In my unit test for
Subject#foo
method, I wanted to stub out theinvalid?
call. My test looks like thisHowever my stub's block never gets called. I imagine its because the stub definite gets 'installed', but since the mixin is done at runtime, the
Validator#invalid?
overwrites my stub. The other option I tried was to stub the method on the modulebut I have the same issue, where my stub block isn't being used/called.
Anyone have any ideas, thoughts or suggestions ?