简体   繁体   中英

cannot access flash[:error] defined in controller method from rspec test

I am new to rails and rspec. I have a custom method in my controller which is not an action. I am trying to test this method using spec.

Here is my controller method:

def find_target_by_id(target_id)    
    begin
      @target = Target.find(target_id)
    rescue ActiveRecord::RecordNotFound
      flash[:error] = "Target with Id #{target_id} does not exist."
      redirect_to root_url
    end
end

Here is my rspec test for this method:

context "is given invalid id" do
   before do
     Target.stub(:find).with("1").and_raise(ActiveRecord::RecordNotFound)
   end
   it "returns flash[:error] " do
     TargetsController.new.find_target_by_id("1")
     flash[:error].should eq("Target with Id 1 does not exist.")
   end

   it "redirects to root url " do
      TargetsController.new.find_target_by_id("1")
      response.should redirect_to(root_url)
   end
end

However, when run the test, I get the error:

Failure/Error: TargetsController.new.find_target_by_id("1").should have(flash[:error])
 RuntimeError:
   ActionController::Base#flash delegated to request.flash, but request is nil: #<TargetsController:0x007fced708ae50 @_routes=nil, @_action_has_layout=true, @_headers={"Content-Type"=>"text/html"}, @_status=200, @_request=nil, @_response=nil>
 # ./app/controllers/targets_controller.rb:71:in `find_target_by_id'
 # ./spec/controllers/targets_controller_spec.rb:212:in `block (4 levels) in <top (required)>'

Any help is much appreciated.

You can't access the flash in Rspec unless an actual web request has been made. That's what the error is suggesting - it's looking at request.flash , but request is nil, as you haven't made a web request.

A few ideas:

  • Make a GET (or POST or whatever) request in your test to an action that calls this method so you can actually have access to the flash
  • Don't set the flash in your helper method, but instead return an error message or raise an exception and leave the flash message setting to your controller action

If I was in this situation, I'd take the second approach. Leave the controllery stuff (like setting the flash and whatnot) to the controller actions and keep your helper methods simple and straightforward. It'll definitely help keep your tests simpler.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM