ell*_*lmo 8 rspec ruby-on-rails devise warden
这是一个非常典型的控制器的规范,before_filter当未登录的用户(也称为访客)尝试访问时,该控制器会重定向到登录页面/projects/new.
describe ProjectsController do
(...)
describe "GET new" do
context 'when not logged in' do
before { sign_in_nobody }
context 'creating project' do
before { get :new }
it 'denies access' do
expect(response).to be_redirect
end
end
end
end
end
Run Code Online (Sandbox Code Playgroud)
我已经specced访问的所有可能的结果:index,:show并:new为来宾,用户,管理员和superadmins.我没有使用任何记录或访客用户,管理员或没有任何问题 - 但这实际上是这个规范第一次涉及涉及Devise的行动,before_filter :autheticate_user!并且它在此失败了.
正如你可能已经怀疑的那样 - 规格甚至没有达到expect(response).to be_redirect,它在之前引发了一个混合:
Failures:
1) ProjectsController GET new when not logged in creating project denies access
Failure/Error: get :new
ArgumentError:
uncaught throw :warden
# ./spec/controllers/projects_controller_spec.rb:344:in `block (5 levels) in <top (required)>'
Run Code Online (Sandbox Code Playgroud)
我已经搜索了一个问题的答案:"如何使用rspec和设计正确测试未经身份验证的(访客)用户",但是每个人只讨论在设计中为RSpec实际记录用户时遇到问题.我解决的问题是:
#spec/support/devise_authenticators.rb
include Devise::TestHelpers
def sign_in_nobody
@request.env["devise.mapping"] = Devise.mappings[:user]
sign_in User.new
end
def sign_in_user
@request.env["devise.mapping"] = Devise.mappings[:user]
sign_in FactoryGirl.create(:user)
end
Run Code Online (Sandbox Code Playgroud)
然而,这不是登录失败,这是"没有记录".到目前为止,我绝对没有和我认识的人HAVE以某种方式测试这些场景.
现在我正在使用一个解决方法:
before { sign_in_nobody }
context 'creating project' do
it 'denies access' do
expect{ get :new }.to raise_exception("uncaught throw :warden")
end
end
Run Code Online (Sandbox Code Playgroud)
但即使它实际上是正确的(uncaught throw :warden仅在authenticate_user!失败时发生,因此可以用作期望)理论上它感觉非常脏.
任何想法如何正确地做到这一点?
(...也许我根本不应该测试这个,看看before_filter authenticate_user!Devise的责任不是我的责任的正确性?)