如何在请求规范中存储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_user
variables在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)