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

发布于 2024-12-04 21:08:36 字数 939 浏览 2 评论 0原文

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

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

其中任何一个都可能吗?

编辑:

这是我所得到的(它不起作用。它只是运行正常的 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

I am needing to stub the response of a current_user method in an Rspec/capybara request spec. The method is defined in ApplicationController and is using helper_method. The method should simply return a user id. Within the test, I'd like this method to return the same user id each time.

Alternatively, I could fix my problem by setting session[:user_id] in the spec (which is what current_user returns)... but that doesn't seem to work either.

Are either of these possible?

Edit:

Here is what I've got (it is not working. It just runs the normal current_user method).

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

Also not working:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

情绪少女 2024-12-11 21:08:36

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

如果您尝试存根的方法是实例方法(最有可能)而不是类方法,那么您需要使用:

ApplicationController.any_instance.stub(:current_user)

skalee seems to have provided the correct answer in the comment.

If the method you're trying to stub is an instance method (most likely) and not a class method then you need use:

ApplicationController.any_instance.stub(:current_user)

时常饿 2024-12-11 21:08:36

以下是基本形式的几个示例。

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

在您的特定情况下,我认为正确的形式是:

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

为了解释我的完整示例,基本上它的作用是验证,当 ActionController::InvalidAuthenticityToken 错误,出现一条 Flash 消息,并且用户将被重定向到 portals_controller#index 操作。您可以使用这些表单来存根并返回特定值、测试引发的给定错误的实例等。有多种 .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

Here are a couple of examples of the basic form.

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

In your particular case, I believe the proper form would be:

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

Here's a full working example from a project I work on:

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

To explain my full example, basically what this does is verify that, when an ActionController::InvalidAuthenticityToken error is raised anywhere in the app, that a flash message appears, and the user is redirected to the portals_controller#index action. You can use these forms to stub out and return specific values, test an instance of a given error being raised, etc. There are several .stub(:action_name).and_[do_something_interesting]() methods available to you.


Update (after you added your code): per my comment, change your code so it reads:

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
迷你仙 2024-12-11 21:08:36

这对我有用,并为我提供了一个在测试中使用的 @current_user 变量。

我有一个如下所示的助手:

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}

This works for me and gives me a @current_user variable to use in tests.

I have a helper that looks like this:

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

And then in my request specs, I call:

before(:each){bypass_authentication}
after(:each){restore_authentication}
东京女 2024-12-11 21:08:36

对于 Rspec 3+,新的 api 是:

对于控制器测试,简洁明了:

allow(controller).to receive(:current_user).and_return(@user)

或者对于 ApplicationController 的所有实例:

allow_any_instance_of(ApplicationController).to receive(:current_user).and_return(@user)

For Rspec 3+ the new api is:

For a controller test, nice and short:

allow(controller).to receive(:current_user).and_return(@user)

Or for all instances of ApplicationController:

allow_any_instance_of(ApplicationController).to receive(:current_user).and_return(@user)
删除→记忆 2024-12-11 21:08:36

对于任何其他碰巧需要存根设置 ivar 的应用程序控制器方法的人(并且因无休止地自慰为什么不应该这样做而受阻),这里有一种可行的方法,具有大约 2013 年 10 月的 Rspec 风格。

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

它存根该方法不执行任何操作,并在 rspec 的控制器实例上设置 ivar,并将其作为 @campaign 提供给测试。

For anyone else who happens to need to stub an application controller method that sets an ivar (and was stymied by endless wanking about why you shouldn't do that) here's a way that works, with the flavour of Rspec circa October 2013.

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

it stubs the method to do nothing, and sets the ivar on rspec's controller instance, and makes it available to the test as @campaign.

一杯敬自由 2024-12-11 21:08:36

提供的回复都不适合我。正如 @matt-fordam 的原始帖子中一样,我有一个请求规范,而不是控制器规范。该测试仅渲染视图而不启动控制器。

我通过在视图上存根方法解决了这个问题,如其他SO帖子中所述

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

None of the provided responses worked for me. As in @matt-fordam's original post, I have a request spec, not a controller spec. The test just renders the view without launching a controller.

I resolved this by stubbing the method on the view as described in this other SO post

view.stub(:current_user).and_return(etc)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文