btakita / rr

RR (Double Ruby) is a test double framework that features a rich selection of double techniques and a terse syntax.
http://github.com/rr/rr
MIT License
501 stars 58 forks source link

Clear up #any_instance_of vs #instance_of #96

Closed mcmire closed 11 years ago

mcmire commented 11 years ago

They both kind of seem to be doing the same thing in code. What do they do? Is there a need to keep both around?

mcmire commented 11 years ago

Also DoubleDefinitionCreate still aliases #instance_of to #any_instance_of, not sure if that's on purpose or what...

mcmire commented 11 years ago

So as far as I can tell, there are two methods because, well, history. But originally there were two use cases:

  1. You want to intercept the .new method of a class, ensuring that .new still creates an instance of a class like it normally would, but then affording you the ability to double inject that instance as soon as it's created.
  2. You don't need to mess with .new, all you want to do is replace an instance method within that class.

new_instance_of was created to solve the first case, and #instance_of (aka #any_instance_of or #all_instances_of) was created to solve the second case. However, they went through some name changes over time:

So, the state of things now is this: we have #any_instance_of which still exists, and then also #instance_of aka #all_instances_of. From the code it looks like #any_instance_of really isn't doing anything anymore -- RR::DoubleDefinitions::DoubleInjections::AnyInstanceOf.call is only called in one place, and without any arguments, all it does is yield the given class to the block. I think it's intended to be called like this:

any_instance_of(Foo, :bar => lambda { 42 })

Whereas #instance_of is intended to be called like this:

instance_of(Foo).bar { 42 }
instance_of(Foo) do
  bar { 42 }
end

We probably just need to deprecate #any_instance_of...

mcmire commented 11 years ago

Just to clarify, DoubleInjection operates on methods within a class. The difference between the AnyInstanceOf and Instance double injection strategies is that Instance gives the metaclass of an object to DoubleInjection whereas AnyInstanceOf gives a class itself.

eliaslevy commented 10 years ago

Its too bad that #new_instance_of was removed. It allows some use cases that the other forms do not allow form. Specifically, it gave you access to the instance from within the stubs, so that you could perform an action or return a value from the stub that depended on the instance.