使用before_action和current_user进行Rspec测试(如Hartl教程中所述)

时间:2014-08-20 14:11:42

标签: ruby-on-rails rspec rspec-rails

我刚刚发现了一些我的测试不断失败的原因,但我修复它的方式似乎并不正确。我想知道这是否可以改善。

我有一个控制器动作,索引,看起来像这样。

class StuffController < ApplicationController
    before_action :signed_in_user

    def index
        @stuff = current_user.stuff
    end
end

signed_in_user方法,直接来自教程:

def signed_in_user
    unless signed_in?
        store_location
        redirect_to signin_url, notice: "Please sign in."
    end
end

当我测试没有登录时访问/ stuff端点的情况时,测试失败,因为:

Failure/Error: get "/stuff"
     NoMethodError:
       undefined method `stuff' for nil:NilClass

我现在知道这是因为,尽管before_action导致响应重定向到signin_url,索引操作仍然完整执行。我将操作更改为此以修复它:

def index
    @stuff = current_user.stuff unless current_user.nil?
end

似乎应该有办法强制重定向停止执行其余的代码,而不是用current_user.nil的两个检查来弄乱每个动作。我确实尝试添加redirect_to signin_url, notice: "Please sign in." and return,但这不起作用。

这是正确的/轨道方式,还是可以改进?

1 个答案:

答案 0 :(得分:0)

我的测试失败的原因是因为我在使用教程中的帮助函数登录时忘记添加no_capybara: true选项。由于这是一个请求规范,capybara DSL不会自动提供。正确的/ rails答案是:

it "does something when logged in" do
  before { sign_in @user, no_capybara: true }
  expect(stuff).to be_stuff
do

sign_in辅助方法显示为here