I have two models:
Student has_many=>:grad_surveys
and
GradSurvey belongs_to=>:student
I am testing the GradSurveysController#update method with
it "should only allow update if the correct token is presented" do
@params = {:id=>"1", :token=>"ab56e1b47",
:survey=>{}}
@mock_grad_survey = mock_model(GradSurvey)
GradSurvey.should_receive(:accepts_as_authorized).with(@params
[:id], at params[:token]).and_return(@mock_grad_survey)
put :update, @params
response.should render_template(:update)
end
Inside the GradSurvey#accepts_as_authorized method is called the
GradSurvey#student method. The test above fails with the message:
Mock ''GradSurvey_1034'' received unexpected message
:student
with (no args)
However I can make the test pass by adding the :student method to the
@mock_grad_survey object, so
@mock_grad_survey = mock_model(GradSurvey, :student=>mock_model
(Student))
Why is it necessary for me to explicitly add the #student method to
the mock GradSurvey model, it seems to me that it should come for free
as part of the defined association, no? What am I not understanding
here?
thanks in advance for any light you are able to shed
David Chelimsky
2009-Aug-04 16:34 UTC
[rspec-users] stubbing association methods in controller spec
On Thu, Jul 30, 2009 at 6:13 PM, norm<codehacker at comcast.net> wrote:> I have two models: > ?Student has_many=>:grad_surveys > ? ?and > ?GradSurvey belongs_to=>:student > > I am testing the GradSurveysController#update method with > > ?it "should only allow update if the correct token is presented" do > ? ?@params = {:id=>"1", :token=>"ab56e1b47", :survey=>{}} > ? ?@mock_grad_survey = mock_model(GradSurvey) > ? ?GradSurvey.should_receive(:accepts_as_authorized).with(@params > [:id], at params[:token]).and_return(@mock_grad_survey) > ? ?put :update, @params > ? ?response.should render_template(:update) > ?end > > Inside the GradSurvey#accepts_as_authorized method is called the > GradSurvey#student method. The test above fails with the message: > ? ? ? ? Mock ''GradSurvey_1034'' received unexpected message :student > with (no args) > > However I can make the test pass by adding the :student method to the > @mock_grad_survey object, so > ? ? ?@mock_grad_survey = mock_model(GradSurvey, :student=>mock_model > (Student)) > > Why is it necessary for me to explicitly add the #student method to > the mock GradSurvey model, it seems to me that it should come for free > as part of the defined association, no? What am I not understanding > here? > > thanks in advance for any light you are able to shedmock_model creates a test double - it''s not a real GradSurvey. Try using stub_model instead: @grad_survey = stub_model(GradSurvey) This uses a real model instance that is modified to not talk to the database. HTH, David