Forum: RSpec Spec'ing a rails controller that does error handling

1ad9efe7a35efa3e1c8369e4f6bfa36a?d=identicon&s=25 Fabio P. (fabio_p96)
on 2013-01-26 19:25
I am trying to spec a controller action that does some error handling,
and I'm having a tough time expressing what I expect in rspec code. The
'create' action is the action in question. It is a fairly standard
create action: it should build a new widget with the values in
params[:widget]. It should then attempt to save the widget and react to
success and failure in the conventional manner.

However, the Widget model, which has a belongs_to relationship with Foo,
has a virtual attribute to create the associated foo. Foo, to complicate
matters, uses single table inheritance, and classes AFoo, BFoo and CFoo
all inherit from Foo. Back to Widget. The virtual attribute on widget
calls Foo.create_by_letter and returns an instance of AFoo, BFoo or CFoo
based on the passed in letter. If there is no letter, or the letter is
not a, b or c, then #create_by_letter raises an InvalidLetterError,
which of course propagates up to the create action.

Back in the create action, it should handle the InvalidLetterError and
try building the widget again, but this time taking out the parameter
that triggers the virtual attribute, and thereby not creating the
associated Foo object. Spec'ing the handling of the error is no problem
("p" below is a dupe of "params" which then has the foo_attrs parameter
removed):

        before(:each) do
          params["widget"]["foo_attrs"]["letter"] = "bogus"
          p["widget"].delete("foo_attrs")
          Widget.stub(:new).
            with(params["widget"]).
            and_raise(InvalidLetterError)
          Widget.stub(:new).
            with(p["widget"]).
            and_return(widget_without_foo)
        end

        it "handles an InvalidLetterError" do
          Widget.should_receive(:new).
            with(params["widget"]).
            and_raise(InvalidLetterError)

          expect {
            post :create, params
          }.to_not raise_error(InvalidLetterError)
        end

But how do I spec that in the error handler it should build the widget
again, without the foo attributes? Here's what I've got so far, and it
passes without any code in the rescue portion of the error handle (i.e.
it passes before I write the code for it to pass):


        it "creates a widget without a foo" do
          RegistrationRequest.should_receive(:new).
            with(p["registration_request"]).
            and_return(widget_without_foo)

          post :create, params
        end

I'm sure I'm doing something very rookie ... hope you can help me figure
out what it is. thx.
This topic is locked and can not be replied to.