Question

Hey, I am trying to use Mocha and Rspec to test a scenario where a method always raises some exception.

Here is the controller code I am trying to test:

  def add_parent
    begin
      parent = Entity.find_by_id(params[:parent_id])
      if !parent.nil?
        @entity.add_parent!(parent)
        flash[:success] = "Entity successfully updated."
      else
        raise "Parent does not exist."
      end
    rescue
      flash[:error] = "Something bad happened. #{$!}"
    end
    redirect_to @entity
  end

Here is the test code:

it "should flash error if exception is thrown when adding parent" do
      Entity.any_instance.stubs(:add_parent!).raises(Exception)
      lambda do
        post :add_parent, :id => @entity[:id], 
          :parent_id => @parent_entity[:id]
      end.should_not change(@entity.parents, :count)
      flash[:error].should =~ /something bad happened/i
    end

Here is the method which is being stubbed:

  def add_parent!(parent)
    Entity.transaction do
      lock!('lock in share mode')
      self.parents << parent
    end
  end

I am getting the following rspec error, which is pretty uninformative so I don't know how to resolve it..

Failures:

  1) EntitiesController POST 'add_parent' for signed-in users allow access with edit permission should flash error if exception is thrown when adding parent
     Failure/Error: post :add_parent, :id => @entity[:id],
     Exception
     # ./app/controllers/entities_controller.rb:81:in `add_parent'
     # ./spec/controllers/entities_controller_spec.rb:1010
Was it helpful?

Solution

Wooah, first of all, it's a very bad habit to rescue from a big chunk of code without give the exception class you are expecting here. rescueing everything is no good. Best remove the whole rescueing, maybe use find over find_by_id so rails can catch that 404 error and you aren't bothered about. On the other hand, is this error supposed to happen a lot? Looks like some db-stuff going on so I wouldn't expect it to fail.

Secondly, I think you must test like the manual says about raise_error http://relishapp.com/rspec/rspec-expectations/v/2-6/dir/built-in-matchers/raise-error-matcher

OTHER TIPS

rescue with no argument will rescue StandardError and its descendants. If you want to catch ALL exceptions, you should rescue Exception as all exceptions descend from class Exception.

Source: http://www.ruby-forum.com/topic/44495

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top