On Sun, Jan 24, 2010 at 5:10 PM, Saverio M. [email protected]
wrote:
class MyController < …
def show
m = MyModel.find( params[ :id ] )
mp = m.my_parent
@m_value = m.value
@mp_value = mp.value
end
end
Hi Saverio,
Following this thread, and still having trouble understanding what it
it you are trying to accomplish.
now, suppose I want to stub a behavior only for the child object (‘m’).
so my intention in the spec is to:
- create the child and his parent
- stub MyModel#value in the child
- stub MyModel.find to return “m” only when called with the child id,
otherwise it should do its usual business. if I stub generically,
m#my_parent would return “m” itself.
The below test does not accomplish this third point… I’ll explain
below.
the test would be:
it “should display a stubbed value for the children” do
mp = MyModel.create!( :value => 0xCAFEBABE )
m = MyModel.create!( :my_parent_id => mp.id, :value => 64738 )
m.stub!( :value ).with( m.id ).and_return( 42 )
Here you are creating a stub on the instance m
, not stubbing
MyModel.find
as you explain above. Perhaps you meant something more
like this?
m.stub!(:value).and_return(42)
MyModel.stub!(:find).with(m.id).and_return(m)
get :show, :id => m.id
Given the text you use in the example description (‘should display a
value for the children’) I wonder why you are passing the child’s id
into the show action. This seems off to me… are you actually
testing that the parent’s value is shown in the action?
end
In fact, since it looks like value
is just an attribute of MyModel
here, I wonder why you would need to stub at all, when you can just
specify the value you are expecting when you create the m
instance
in the test? It is hard to tell since you aren’t including any
verification in the example you gave. What is it you are actually
trying to test here? My best guess would be that you’re going for
something like this:
it “displays parent’s :value attribute” do
expected_value = 386438247
value_i_dont_care_about = 123
mp = MyModel.create!( :value => expected_value )
m = MyModel.create!( :my_parent_id => mp.id, :value =>
value_i_dont_care_about )
get “show”, :id => m.id
response.should include(expected_value)
end
The above tests that when you render a “show” for instance m
that
m
’s parent’s ‘value’ attribute shows up somewhere on the page.
What are you hoping for the stub to accomplish for you in this test?
what happens is:
- if I don’t use “.with( m.id )”, @m_value and @mp_value will have
m.value assigned.
This makes sense if you are indeed stubbing MyModel.find
without
using with
similar to my guess above, since any arguments you pass
would be ignored and the instance m
would be returned in all cases.
- if I use “.with( m.id )”, I even get an error “undefined method `find’
for #Class:0x7f2b3116a2c0” at the line “self.find( my_parent_id )”
inside the method MyModel#my_parent.
This is odd, and I’m not sure without more context why this would be
happening. My guess is that something else wasn’t wired up correctly
when you tried to do this.
Hope this clarified, it’s not real production code, but it models a
behavior sometimes I actually needed.
I think some more clarification is needed in order for us to properly
help you.
a) What is the exact behavior you are trying to test?
b) Why do you believe that a stub would help you test this behavior?
Hope this helps get us going in the right direction at least,
Paul