Understanding Rails 3's respond_with

前端 未结 1 2042
小蘑菇
小蘑菇 2021-02-01 09:38

Utilizing ActionController\'s new respond_with method...how does it determine what to render when action (save) is successful and when it\'s not?

I ask bec

1条回答
  •  既然无缘
    2021-02-01 09:54

    tl:dr

    Add an error hash to the mock:

    Carrier.stub(:new) { mock_carrier(:save => false, 
                           :errors => { :anything => "any value (even nil)" })}
    

    This will trigger the desired behavior in respond_with.

    What is going on here

    Add this after the post :create

    response.code.should == "200"
    

    It fails with expected: "200", got: "302". So it is redirecting instead of rendering the new template when it shouldn't. Where is it going? Give it a path we know will fail:

    response.should redirect_to("/")
    

    Now it fails with Expected response to be a redirect to but was a redirect to

    The spec is supposed to pass by rendering the new template, which is the normal course of events after the save on the mock Carrier object returns false. Instead respond_with ends up redirecting to show_carrier_path. Which is just plain wrong. But why?

    After some digging in the source code, it seems that the controller tries to render 'carriers/create'. There is no such template, so an exception is raised. The rescue block determines the request is a POST and there is nothing in the error hash, upon which the controller redirects to the default resource, which is the mock Carrier.

    That is puzzling, since the controller should not assume there is a valid model instance. This is a create after all. At this point I can only surmise that the test environment is somehow taking shortcuts.

    So the workaround is to provide a fake error hash. Normally something would be in the hash after save fails, so that kinda makes sense.

    0 讨论(0)
提交回复
热议问题