2012-12-20 23 views
1

我是rails和rspec的新手。我在我的控制器中有一个自定义方法,这不是一个动作。我试图用spec来测试这个方法。无法访问从rspec测试中定义的控制器方法中的flash [:error]

这里是我的控制器方法:

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 

这里是我的这个方法RSpec的测试:

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 

但是,当运行测试,我得到的错误:

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)>' 

任何帮助,非常感谢。

+0

您是否设法找到一种在Rails控制器中测试非操作方法的好方法? –

回答

1

您不能访问Rspec中的闪存,除非实际的Web请求已经完成。这就是错误提示 - 它正在查看request.flash,但request为零,因为您还没有发出网络请求。

几个想法:

  • 请在您的测试一个GET(或POST或其他)请求调用此方法的动作,所以你其实可以有机会获得闪光
  • 不要设置在你的帮手方法中闪光,但相反返回一个错误信息或引发异常,并保留闪光灯消息设置为您的控制器行动

如果我在这种情况下,我会采取第二种方法。把控制器的东西放在控制器的操作上(比如设置flash和whatnot),并保持你的帮助器方法简单明了。它肯定会帮助你保持简单的测试。

+0

谢谢BaronVonBraun的快速回复。我现在看到它。我在这个辅助方法中设置flash的原因是因为这是由控制器内的多个动作调用的。因此,如果我将错误设置为控制器操作,我的代码中会有很多冗余。我很困惑... –

相关问题