0

Here is the error in rspec:

CategoriesController GET 'update' should be successful
 Failure/Error: get 'update'
 ActiveRecord::RecordNotFound:
   Couldn't find Category without an ID
 # c:in `find'
 # ./app/controllers/categories_controller.rb:45:in `update'
 # ./spec/controllers/categories_controller_spec.rb:35:in `block (3 levels) in <top (required)>'

Here is the code in controller:

  def edit
    @category = Category.find(params[:id])
  end

  def update
    @category = Category.find(params[:id])
    #@category.reload. caused nil.reload error

    if @category.update_attributes(params[:category], :as => :roles_update)  
      @category = Category.find(params[:id])
      redirect_to @category, :notice => 'Category was successfully updated'
    else
      @categories = Category.all
      render 'index'
    end 
  end

Here is the rspec code:

  describe "GET 'update'" do
    it "should be successful" do
      get 'update'
      response.should be_success
    end
  end

Any thoughts? Thanks.

1 Answer 1

1

You pasted the create action instead of the update action. Also, you are trying to test the update action with a get request.. it should be with a put request if you are following the conventions.

If you had, say, the update action implemented... you would test more or less like:

describe CategoriesController do
  let(:category) { mock_model(Category).as_null_object }

  describe "PUT update" do
    before do
      Category.should_receive(:find).with(5).and_return(category)
    end

    context "when a category updates succesfully" do
      before do
        category.stub(:update_attributes).and_return(true)
      end

      it "redirects to the categories page" do
        put :update, :id => 5, :category => { :some_val => 4 }
        response.should redirect_to(categories_path)
      end

      it "sets the flash message" do
        put :update, :id => 5, :category => { :some_val => 4 }
        flash[:notice].should eq("Category was succesfully updated")
      end
    end

    context "when a category does not update successfully" do
      before do
        category.stub(:update_attributes).and_return(false)
      end

      it "sets the flash message"
      it "redirects to the categories page"

      # etc etc
    end
  end
end

To get to this point (meaning the addition of mock models, stubs, what have you) you would normally start "fresh" so to speak and work your way up TDD style. Hope it helps

Sign up to request clarification or add additional context in comments.

5 Comments

posted the method update and edit. Will test your solution. Thanks.
If you are going to use the sample code I posted, you should change response.should redirect_to(categories_path) to the path of the category being updated (which is what you are doing in the update action)
still trying. There are a few category records in the table and I just pick one of them to "put update, :id => 2, :category => {:active => false} " in rspec. Still have the ActiveRecord::RecordNotFound:Couldn't find Category with id=2. But I can pull out the record with Category.find(2) in rails console.
It is because you are running under the testing environment, your records exist only in the development environment. In this case, you are passing an ID of 2. You need to stub the find method and return a mock object. You are not actually retrieving the record from the database, rspec prevents it and provides the mock instead. In the code sample, I instructed rspec to return a mock object but I enforced that the find method must be called with an ID of 5. To get your test with ID 2 running, just replace to: Category.should_receive(:find).with(2).and_return(category)
I recommend you read articles and samples, perhaps books on testing with libraries such as rspec. This particular sample code would be at the end of reaching the desired functionality for say... the update action. The whole process and point of testing is a lot more than that. You go through TDD cycles and as you go green throughout red cycles you start mocking, which makes running your tests a little faster somewhat.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.