如何在请求规范中存储ApplicationController方法

我需要在Rspec / capybara请求规范中存根current_user方法的响应。 该方法在ApplicationController定义,并使用helper_method。 该方法应该简单地返回一个用户ID。 在testing中,我希望这种方法每次都返回相同的用户ID。

或者,我可以通过在spec(这是current_user返回的内容)中设置session[:user_id]来解决我的问题…但是这似乎也不起作用。

这两者中的哪一个可能?

编辑:

这是我得到的(它不工作,它只是运行正常的current_user方法)。

 require 'spec_helper' describe "Login" do before(:each) do ApplicationController.stub(:current_user).and_return(User.first) end it "logs in" do visit '/' page.should have_content("Hey there user!") end end 

也不工作:

 require 'spec_helper' describe "Login" do before(:each) do @mock_controller = mock("ApplicationController") @mock_controller.stub(:current_user).and_return(User.first) end it "logs in" do visit '/' page.should have_content("Hey there user!") end end 

skalee似乎已经在评论中提供了正确的答案。

如果你试图存根的方法是一个实例方法(最可能),而不是一个类方法,那么你需要使用:

ApplicationController.any_instance.stub(:current_user)

这里有几个基本forms的例子。

 controller.stub(:action_name).and_raise([some error]) controller.stub(:action_name).and_return([some value]) 

在你的具体情况下,我认为适当的forms是:

 controller.stub(:current_user).and_return([your user object/id]) 

下面是我正在从事的一个项目的一个完整的工作示例:

 describe PortalsController do it "if an ActionController::InvalidAuthenticityToken is raised the user should be redirected to login" do controller.stub(:index).and_raise(ActionController::InvalidAuthenticityToken) get :index flash[:notice].should eql("Your session has expired.") response.should redirect_to(portals_path) end end 

为了解释我的完整示例,基本上这样做是validation,当在应用程序中的任何位置引发ActionController::InvalidAuthenticityToken错误时,将显示一条Flash消息,并将用户redirect到portals_controller#index操作。 您可以使用这些表单来存根和返回特定值,testing引发的给定错误的实例等等。您可以使用几个.stub(:action_name).and_[do_something_interesting]()方法。


更新 (在您添加代码后):根据我的评论,更改您的代码,使其显示如下:

 require 'spec_helper' describe "Login" do before(:each) do @mock_controller = mock("ApplicationController") @mock_controller.stub(:current_user).and_return(User.first) end it "logs in" do visit '/' page.should have_content("Hey there user!") end end 

这对我@current_user ,给了我一个@current_uservariables在testing中使用。

我有一个看起来像这样的帮手:

 def bypass_authentication current_user = FactoryGirl.create(:user) ApplicationController.send(:alias_method, :old_current_user, :current_user) ApplicationController.send(:define_method, :current_user) do current_user end @current_user = current_user end def restore_authentication ApplicationController.send(:alias_method, :current_user, :old_current_user) end 

然后在我的请求规范中,我打电话给:

 before(:each){bypass_authentication} after(:each){restore_authentication} 

对于任何碰巧需要设置一个ivar的应用程序控制器方法的人来说(这个方法被无尽的讨厌,为什么你不应该这样做),这是一个有效的方法,大约在2013年10月。

 before(:each) do campaign = Campaign.create! ApplicationController.any_instance.stub(:load_campaign_singleton) controller.instance_eval{@campaign = campaign} @campaign = campaign end 

它存根的方法什么也不做,并设置在rspec的控制器实例上的伊娃,并作为@campaigntesting可用。

没有提供的答复为我工作。 正如在@ matt-fordam的原文中,我有一个请求规范,而不是一个控制器规范。 testing只是渲染视图而不启动控制器。

我解决了这个问题,就像在这个其他的SOpost中描述的那样在视图上存根方法

 view.stub(:current_user).and_return(etc)